QOJ.ac
QOJ
ID | 题目 | 提交者 | 结果 | 用时 | 内存 | 语言 | 文件大小 | 提交时间 | 测评时间 |
---|---|---|---|---|---|---|---|---|---|
#590618 | #6837. AC Automaton | ydzr00000 | WA | 9ms | 61856kb | C++17 | 5.5kb | 2024-09-26 09:00:02 | 2024-09-26 09:00:04 |
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 cnt[300001],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)
{
cnt[now]=(id[now]>0);
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);
cnt[now]+=cnt[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[150001],rnk[150001],sz[150001],anc[150001];
inline void getorder(int now)
{
ord[++top]=now;
rnk[now]=top;
sz[now]=1;
for(auto to: vr[now])
{
getorder(to);
anc[to]=now;
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<=Bnum;i++)
B[i].init(L);
//Calculate
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;
};
for(int i=st;i<=ed;i++)
{
int u=ord[i];
change(id[u],op);
if(u<=s)
{
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]=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();
};
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;
}
详细
Test #1:
score: 100
Accepted
time: 6ms
memory: 42560kb
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: 9ms
memory: 61856kb
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 2798 2798 2802 2802 2802 2802 2802 2802 2802 2797 2797 2797 2797 2794 2796 2796 2800 2796 2792 2795 2798 2803 2803 2803 2803 2803 2803 2777 2777 2777 2777 2774 2771 2774 2783 2779 2779 2773 2769 2772 2772 2772 2772 2772 2774 2774 2779 2782 2782 2780 2784 2786 2789 2784 2788 2790 ...
result:
wrong answer 5th lines differ - expected: '2768', found: '2798'