QOJ.ac

QOJ

IDProblemSubmitterResultTimeMemoryLanguageFile sizeSubmit timeJudge time
#393288#6837. AC AutomatonmarherRE 15ms156916kbC++144.0kb2024-04-18 14:01:482024-04-18 14:01:49

Judging History

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

  • [2024-04-18 14:01:49]
  • 评测
  • 测评结果:RE
  • 用时:15ms
  • 内存:156916kb
  • [2024-04-18 14:01:48]
  • 提交

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]=t[0]=1;
	for(int i=1;i<=k;i++)if(t[i]!=t[i-1])
	{
		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;
        for(auto x:p)if(s[x]=='A')++num,sum+=f[x];
        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;
        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])
    {
        int rw=dfs(v,r);
        if(rw!=0&&w!=0&&in[x]==0)exit(1);
        w+=rw;
    }
    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)
{
    int rx=x;
    if(c!='A')
    {
        d1[x].fad(w),d1[x].gad(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')
    {
        d2[x=rx].gad(-w);
        for(auto v:to[x])GAD(v,-w);
    }
}

void sol()
{
    int ans=0;
    for(auto x:vt)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();
    for(int i=1;i<=q;i++)mk(p[i],s[p[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;
}

Details

Tip: Click on the bar to expand more detailed information

Test #1:

score: 100
Accepted
time: 15ms
memory: 156916kb

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
Runtime Error

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:


result: