QOJ.ac

QOJ

ID题目提交者结果用时内存语言文件大小提交时间测评时间
#393185#6837. AC AutomatonmarherWA 20ms161104kbC++144.2kb2024-04-18 11:40:322024-04-18 11:40:32

Judging History

你现在查看的是最新测评结果

  • [2024-04-18 11:40:32]
  • 评测
  • 测评结果:WA
  • 用时:20ms
  • 内存:161104kb
  • [2024-04-18 11:40:32]
  • 提交

answer

#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N=7e5+50;

int n,q,f[N],g[N],B,fa[N],ff[N],top[N],siz[N],son[N],dep[N],p[N],t[N],dfn[N],now[N],in[N];
vector<int>to[N],vt,tson[N];
char s[N],c[N];

int LCA(int u,int v)
{
    while(top[u]!=top[v])
    {
        if(dep[top[u]]<dep[top[v]])swap(u,v);
        u=fa[top[u]];
    }
    return dep[u]<dep[v]?u:v;
}

int st[N];

void ADD(int x,int y)
{
    to[x].push_back(y);ff[y]=x;in[x]=in[y]=1;
}

void add(int&top)
{
	ADD(st[top-1],st[top]);
	top--;
}

void rebuild(int k)
{
	int top=0;st[++top]=1;in[1]=1;
	for(int i=1;i<=k;i++)
	{
		int lca=LCA(t[i],st[top]);
		while(dep[lca]<=dep[st[top-1]])add(top);
		if(lca!=st[top])ADD(lca,st[top]),st[top]=lca;
		if(t[i]!=lca)st[++top]=t[i];
	}
	while(top>1)add(top);
}

int cmp(int a,int b)
{
    return dfn[a]<dfn[b];
}

struct node
{
    int x,num,sum;
};

int w[N];

struct block
{
    vector<int>p;
    vector<node>a;
    int num,n,sum;// F
    int pos,ad;//G

    void clear()
    {
        vector<int>().swap(p);
        vector<node>().swap(a);
        num=n=sum=pos=ad=0;
    }

    void init()
    {
        for(auto x:p)if(s[x]=='?')w[++n]=g[x];w[++n]=1e9;
        sort(w+1,w+1+n);n=unique(w+1,w+1+n)-w-1;
        a.resize(n+1,(node){0,0,0});a[0].x=-1e9;
        for(int i=1;i<=n;i++)a[i].x=w[i];
        for(auto x:p)if(s[x]=='?')
        {
            int val=g[x],pos=lower_bound(w+1,w+1+n,val)-w;
            a[pos].num++;a[pos].sum+=val;
        }
        for(int i=n-1;i>=0;i--)a[i].sum+=a[i+1].sum,a[i].num+=a[i+1].num;
        for(int i=1;i<=n;i++)if(w[i]>0)
        {
            pos=i;
            break;
        }
    }

    void fad(int x)
    {
        sum+=x*num;
    }

    void gad(int x)
    {
        ad-=x;
        // cout<<ad<<' '<<x<<' '<<pos<<' '<<a.size()<<' '<<n<<'\n';
        if(x>0&&a[pos-1].x>ad)pos--;
        if(x<0&&a[pos].x<=ad)pos++;
    }

    int sol()
    {
        return sum+a[pos].sum-ad*a[pos].num;
    }
}d1[N],d2[N];//d1 : chain , d2 : subtree

void clear(int x)
{
    in[x]=ff[x]=0;
    d1[x].clear();
    d2[x].clear();
    for(auto v:to[x])clear(v);
    vector<int>().swap(to[x]);
}

int dfs(int x,int r)
{
    if(in[x])r=x;
    int w=0;
    for(auto v:tson[x])w=dfs(v,r);
    if(!in[x])
    {
        if(w)d1[w].p.push_back(x);
        else d2[r].p.push_back(x);
    }
    return in[x]?x:w;
}

void GAD(int x,int w)
{
    d1[x].gad(w);d2[x].gad(w);g[x]+=w;
    for(auto v:to[x])GAD(v,-w);
}

void mk(int x,char c,int w)
{
    // cout<<"find\n";
    int rx=x;
    if(c!='A')
    {
        // cout<<"S1\n";
        d1[x].fad(w),x=ff[x];
        while(x)d1[x].fad(w),d1[x].gad(w),f[x]+=w,g[x]+=w,x=ff[x];
    }
    if(c!='C')
    {
        // cout<<rx<<' '<<in[rx]<<' '<<"S2\n";
        d2[x=rx].gad(-w);
        for(auto v:to[x])GAD(v,-w);
    }
}

void sol()
{
    int ans=0;
    for(auto x:vt)
    {
        // cout<<x<<' '<<s[x]<<' '<<f[x]<<' '<<g[x]<<' '<<d1[x].sol()<<' '<<d2[x].sol()<<'\n';
        ans+=(s[x]=='A')*f[x]+(s[x]=='?')*max(0ll,g[x])+d1[x].sol()+d2[x].sol();
    }
    cout<<ans<<'\n';
}

void solve(int q)
{
    vector<int>().swap(vt);
    for(int i=1;i<=n;i++)f[i]=g[i]=0;
    for(int i=n;i>=1;i--)f[fa[i]]+=f[i]+(s[i]!='A');
    for(int i=2;i<=n;i++)g[i]=g[fa[i]]-(s[fa[i]]!='C');
    for(int i=1;i<=n;i++)g[i]+=f[i];
    for(int i=1;i<=q;i++)cin>>p[i]>>c[i],t[i]=p[i];
    sort(t+1,t+1+q,cmp);rebuild(q);dfs(1,1);
    for(int i=1;i<=n;i++)if(in[i])vt.push_back(i),d1[i].init(),d2[i].init();
    // sol();return;
    for(int i=1;i<=q;i++)mk(p[i],s[i],-1),mk(p[i],c[i],1),s[p[i]]=c[i],sol();
    clear(1);
}

main()
{
    // freopen("in.txt","r",stdin);
    cin>>n>>q>>(s+1);B=sqrt(q);dep[1]=1;
    for(int i=2;i<=n;i++)cin>>fa[i],dep[i]=dep[fa[i]]+1,tson[fa[i]].push_back(i);
    for(int i=n;i>=1;i--)siz[i]++,siz[fa[i]]+=siz[i];
    siz[0]=0;dfn[1]=now[1]=top[1]=1;
    for(int i=2;i<=n;i++)
    {
        if(siz[i]>siz[son[fa[i]]])son[fa[i]]=i;
        dfn[i]=now[fa[i]]+1;now[fa[i]]+=siz[i];
        top[i]=son[fa[i]]==i?top[fa[i]]:i;
    }
    while(q>0)solve(min(q,B)),q-=B;
}

详细

Test #1:

score: 100
Accepted
time: 20ms
memory: 158880kb

input:

5 3
AC??C
1 2 2 1
1 ?
4 A
2 ?

output:

4
3
3

result:

ok 3 lines

Test #2:

score: -100
Wrong Answer
time: 11ms
memory: 161104kb

input:

1000 1000
AC?ACCCCC?CCA??CCCCC?A?AC?C??C?ACCCACC?C?CCC?CACACA???????C?????CC?C?AAAAACCA??AAAACACACA???AACAC?CCC?CAC?AAAACCAC???ACAA??A??A?CA?A?ACACACCAA?ACACA?AC??AC??ACAAACCC??CAA?A???CC?AA??AC???A?CCCC??CACCAACC?AA?C?AAACCCA?AAA??C?CC??CACCACAACCA?AACCC?A?CCC?CC???AA?CACCCAAC??CAA??C?AA??CA???CAAA...

output:

1479
1477
1476
1475
1906
1906
1905
1905
1904
1904
1904
1904
1904
1902
1900
1900
1900
1898
1893
1893
1893
1893
1892
1891
1891
1896
1896
1898
1898
1898
1898
2132
2135
2135
2136
2137
2136
2135
2135
2135
2132
2130
2128
2129
2126
2126
2126
2123
2121
2121
2121
2121
2122
2121
2122
2119
2118
2115
2115
2114
...

result:

wrong answer 1st lines differ - expected: '2344', found: '1479'