QOJ.ac
QOJ
ID | Problem | Submitter | Result | Time | Memory | Language | File size | Submit time | Judge time |
---|---|---|---|---|---|---|---|---|---|
#590750 | #6837. AC Automaton | ydzr00000 | WA | 19ms | 42616kb | C++17 | 5.5kb | 2024-09-26 10:55:34 | 2024-09-26 10:55:34 |
Judging History
answer
#include<bits/stdc++.h>
using namespace std;
vector<int>e[300001],vr[300001];
int ch[300001];
int dep[300001],fir[300001],top=0,dfn[600001];
int st[600001][20],lg2[600001];
int up[300001][3],down[300001][3];
inline void dfs(int now)
{
dfn[++top]=now;
fir[now]=top;
for(auto to: e[now])
{
dep[to]=dep[now]+1;
dfs(to);
dfn[++top]=now;
}
}
inline int LCA(int u,int v)
{
u=fir[u];v=fir[v];
if(u>v)
swap(u,v);
int t=lg2[v-u+1];
int x=st[u][t],y=st[v-(1<<t)+1][t];
return dep[x]<dep[y]?x:y;
}
vector<pair<int,int>>op;
int bel[300001],fa[300001];
int f[300001],g[300001];
vector<int>point;
int upnode[300001],dwnode[300001],id[300001],vf[300001];
inline void calc(int now)
{
up[now][ch[now]]++;
down[now][ch[now]]++;
for(auto to: e[now])
{
for(int i=0;i<3;i++)
up[to][i]+=up[now][i];
calc(to);
for(int i=0;i<3;i++)
down[now][i]+=down[to][i];
}
}
struct Block{
int buf[3001],del;
int cnt0,cnt2;
int tagf,tagg;
long long sumf,sumg;
inline void init(int L)
{
tagf=tagg=0;
sumf=sumg=0;
cnt0=cnt2=0;del=L;
fill(buf,buf+2*L+1,0);
}
inline void updateF(int val)
{
sumf-=tagf*cnt0;
tagf+=val;
sumf+=tagf*cnt0;
}
inline void updateG(int val)
{
if(val==1)
{
tagg++;
cnt2+=buf[del-tagg];
sumg+=cnt2;
}
else
{
sumg-=cnt2;
cnt2-=buf[del-tagg];
tagg--;
}
}
}B[3001];
int ord[15001],rnk[300001],sz[300001],anc[300001];
inline void getorder(int now)
{
ord[++top]=now;
rnk[now]=top;
sz[now]=1;
for(auto to: vr[now])
{
anc[to]=now;
getorder(to);
sz[now]+=sz[to];
}
}
int main(){
int n,q;
scanf("%d %d",&n,&q);
string str;
cin>>str;
for(int i=0;i<n;i++)
ch[i+1]=(str[i]=='?'?2:(str[i]=='A'?0:1));
for(int i=2;i<=n;i++)
{
int f;
scanf("%d",&f);
fa[i]=f;
e[f].push_back(i);
}
dep[1]=1;
dfs(1);
for(int i=1;i<=top;i++)
st[i][0]=dfn[i];
lg2[0]=-1;
for(int i=1;i<=top;i++)
lg2[i]=lg2[i>>1]+1;
for(int i=1;i<=lg2[top];i++)
for(int j=1;j+(1<<i)-1<=top;j++)
{
int u=st[j][i-1],v=st[j+(1<<(i-1))][i-1];
st[j][i]=(dep[u]<dep[v]?u:v);
}
// int L=(int)sqrt(1.00*q);
int L=1;
auto solve=[&]()->void
{
//Build of Virtual Tree
for(auto [x,c]: op)
point.push_back(x);
point.push_back(1);
sort(point.begin(),point.end(),[&](const int &x,const int &y){
return fir[x]<fir[y];
});
point.erase(unique(point.begin(),point.end()),point.end());
int s=point.size();
for(int i=0;i<s-1;i++)
point.push_back(LCA(point[i],point[i+1]));
sort(point.begin(),point.end(),[&](const int &x,const int &y){
return fir[x]<fir[y];
});
point.erase(unique(point.begin(),point.end()),point.end());
s=point.size();
for(int i=0;i<s-1;i++)
{
int u=LCA(point[i],point[i+1]);
vf[i+1]=u;
vr[u].push_back(point[i+1]);
}
//Block
for(int i=0;i<s;i++)
id[point[i]]=i+1;
for(int i=0;i<s;i++)
{
int x=point[i];
while(x!=vf[i])
{
dwnode[x]=point[i];
x=fa[x];
}
}
for(int i=1;i<=n;i++)
upnode[i]=(id[i]?i:upnode[fa[i]]);
int Bnum=0;
for(int i=1;i<=n;i++)
if(!id[i])
{
bel[i]=(dwnode[i]?id[dwnode[i]]:id[upnode[i]]+s);
Bnum=max(Bnum,bel[i]);
}
for(int i=1;i<=2*s;i++)
B[i].init(L);
//Calculate
top=0;
calc(1);getorder(1);
long long ans=0;
for(int i=1;i<=n;i++)
{
f[i]=down[i][1]+down[i][2];
g[i]=down[i][1]+down[i][2]-up[i][0]-up[i][2];
int Bid=bel[i];
if(!Bid)
{
ans+=(ch[i]==0)*f[i]+(ch[i]==2)*max(g[i],0);
continue;
}
if(ch[i]==0)
{
B[Bid].sumf+=f[i];
B[Bid].cnt0++;
}
if(ch[i]==2)
{
B[Bid].sumg+=max(g[i],0);
if(g[i]>=0)
B[Bid].cnt2++;
if(g[i]>=-L&&g[i]<=L)
B[Bid].buf[g[i]+L]++;
}
}
for(int i=1;i<=Bnum;i++)
ans+=B[i].sumf+B[i].sumg;
auto updateU=[&](int x,int op)->void
{
auto change=[&](int x,int op)->void
{
ans-=B[x].sumf+B[x].sumg;
B[x].updateF(op);B[x].updateG(op);
ans+=B[x].sumf+B[x].sumg;
};
change(id[x],op);
while(anc[x])
{
x=anc[x];
change(id[x],op);
ans-=(ch[x]==0)*f[x]+(ch[x]==2)*max(g[x],0);
f[x]+=op;g[x]+=op;
ans+=(ch[x]==0)*f[x]+(ch[x]==2)*max(g[x],0);
}
};
auto updateD=[&](int x,int op)->void
{
int st=rnk[x]+1,ed=rnk[x]+sz[x]-1;
auto change=[&](int x,int op)->void
{
ans-=B[x].sumg;
B[x].updateG(op);
ans+=B[x].sumg;
};
change(id[x]+s,op);
for(int i=st;i<=ed;i++)
{
int u=ord[i];
change(id[u],op);change(id[u]+s,op);
ans-=(ch[u]==2)*max(g[u],0);
g[u]+=op;
ans+=(ch[u]==2)*max(g[u],0);
}
};
auto updateN=[&](int x,int typ,int op)->void
{
if(typ==0)
ans+=op*f[x],g[x]-=op;
else if(typ==1)
f[x]+=op,g[x]+=op;
else
f[x]+=op,ans+=op*max(g[x],0);
};
for(auto [x,c]: op)
{
if(ch[x]!=c)
{
updateN(x,ch[x],-1);
if(ch[x]!=0) updateU(x,-1);
if(ch[x]!=1) updateD(x,1);
ch[x]=c;
if(ch[x]!=0) updateU(x,1);
if(ch[x]!=1) updateD(x,-1);
updateN(x,ch[x],1);
}
printf("%lld\n",ans);
}
//Clear
for(int i=1;i<=n;i++)
{
id[i]=bel[i]=anc[i]=0;
for(int j=0;j<3;j++)
up[i][j]=down[i][j]=0;
}
for(int i=1;i<s;i++)
vr[vf[i]].clear();
op.clear();point.clear();
};
for(int i=1;i<=q;i++)
{
int x;
char c;
scanf("%d %c",&x,&c);
op.push_back({x,(c=='?'?2:(c=='A'?0:1))});
if(i%L==0||i==q)
solve();
}
return 0;
}
Details
Tip: Click on the bar to expand more detailed information
Test #1:
score: 100
Accepted
time: 4ms
memory: 42276kb
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: 19ms
memory: 42616kb
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:
2344 2345 2342 2342 2762 2768 2772 2772 2772 2772 2772 2772 2772 2767 2767 2767 2767 2764 2766 2766 2770 2765 2761 2764 2767 2771 2772 2772 2772 2772 2772 2777 2777 2777 2777 2774 2771 2774 2783 2778 2778 2772 2768 2772 2772 2772 2772 2772 2774 2774 2779 2781 2781 2779 2783 2784 2787 2782 2786 2788 ...
result:
wrong answer 5th lines differ - expected: '2768', found: '2762'