QOJ.ac
QOJ
ID | Problem | Submitter | Result | Time | Memory | Language | File size | Submit time | Judge time |
---|---|---|---|---|---|---|---|---|---|
#178991 | #6837. AC Automaton | Crysfly | RE | 3ms | 36940kb | C++17 | 4.9kb | 2023-09-14 16:17:10 | 2023-09-14 16:17:12 |
Judging History
answer
#include<bits/stdc++.h>
#define For(i,a,b) for(int i=(a);i<=(b);++i)
#define Rep(i,a,b) for(int i=(a);i>=(b);--i)
#define ll long long
using namespace std;
inline int read()
{
char c=getchar();int x=0;bool f=0;
for(;!isdigit(c);c=getchar())f^=!(c^45);
for(;isdigit(c);c=getchar())x=(x<<1)+(x<<3)+(c^48);
if(f)x=-x;return x;
}
#define fi first
#define se second
#define pb push_back
#define mkp make_pair
typedef pair<int,int>pii;
typedef vector<int>vi;
#define maxn 200005
#define inf 0x3f3f3f3f
int n,m;
char s[maxn];
vi e[maxn];
int fa[maxn],dep[maxn],sz[maxn];
int dfn[maxn],que[maxn],out[maxn],idx;
int st[20][maxn],lg[maxn];
int depmin(int u,int v){return dep[u]<dep[v]?u:v;}
void dfs(int u){
dfn[u]=++idx,que[idx]=u,sz[u]=1;
for(auto v:e[u]){
if(v==fa[u])continue;
fa[v]=u,dep[v]=dep[u]+1;
dfs(v),sz[u]+=sz[v];
}out[u]=idx;
}
void init(){
dfs(1);
For(i,2,n)st[0][i]=fa[que[i]],lg[i]=lg[i>>1]+1;
For(j,1,19)
For(i,1,n-(1<<j)+1)
st[j][i]=depmin(st[j-1][i],st[j-1][i+(1<<(j-1))]);
}
int lca(int u,int v){
if(u==v)return u;
if((u=dfn[u])>(v=dfn[v]))swap(u,v); ++u;
int k=lg[v-u+1];
return depmin(st[k][u],st[k][v-(1<<k)+1]);
}
int dist(int u,int v){
if(!u||!v)return -((!u)+(!v));
return dep[u]+dep[v]-2*dep[lca(u,v)];
}
bool dfncmp(int u,int v){
return dfn[u]<dfn[v];
}
int qu[maxn]; char qc[maxn];
int f[maxn],g[maxn];
ll sum;
bool is1(char c){return c=='C'||c=='?';}
bool is0(char c){return c=='A'||c=='?';}
void predp(int u,int c=0){
f[u]=is1(s[u]);
c+=is0(s[u]);
for(int v:e[u])predp(v,c),f[u]+=f[v];
g[u]=f[u]-c;
}
int B;
/*
询问分块,虚树
每次:
加一条祖先链的 f,g
加 子树的 g
f easy
max(g,0) 对虚树上每个部分暴力修改
*/
// B = 500 个询问一块
int *c[4005],ccc[4005][4005],c0[4005],cg[4005];
void inic(){
For(i,0,4004) c[i]=ccc[i]+2002;
}
int p[maxn],len;
int vfa[maxn];
vi G[maxn];
int in[maxn],up[maxn],dw[maxn],bel[maxn];
void ins(int id,int u){
bel[u]=id;
if(s[u]=='A')++c0[id];
else if(s[u]=='?'){
if(g[u]>0) ++cg[id];
if(g[u]>=-B && g[u]<=B) ++c[id][g[u]];
}
}
// f+=1,g+=1,g-=1
int tagf[maxn],tagg[maxn];
void addf(int u,int w){
tagf[u]+=w;
sum+=w*c0[u];
// cout<<"addf "<<u<<" "<<w<<endl;
}
void addg(int u){
cg[u]+=c[u][-tagg[u]];
++tagg[u];
sum+=cg[u];
}
void subg(int u){
--tagg[u];
sum-=cg[u];
cg[u]-=c[u][-tagg[u]];
}
void addg(int u,int op){
// cout<<"addg "<<u<<" "<<op<<endl;
if(op==1) addg(u);
else subg(u);
}
void MDF(int u,char ch,int op){
// cout<<"u: "<<u<<" "<<f[u]<<" "<<g[u]<<" "<<s[u]<<'\n';
if(ch=='C') f[u]+=op,g[u]+=op;
if(ch=='A') sum+=f[u]*op,g[u]-=op;
if(ch=='?') sum+=max(g[u],0)*op,f[u]+=op;
}
void mdfanc(int u,int op){
// cout<<"mdfanc "<<u<<" "<<op<<endl;
int x=u;
while(x){
addf(in[x],op);
addg(in[x],op);
x=vfa[x];
if(!x)break;
if(s[x]=='?') sum-=max(g[x],0);
if(s[x]=='A') sum+=op;
f[x]+=op,g[x]+=op;
if(s[x]=='?') sum+=max(g[x],0);
}
}
int Q[maxn],hd,tl;
void mdfsub(int u,int op){
// cout<<"mdfsub "<<u<<" "<<op<<endl;
Q[hd=tl=1]=u;
while(hd<=tl){
int x=Q[hd++];
if(x!=u){
addg(in[x],-op);
if(s[x]=='?') sum-=max(0,g[x]);
g[x]-=op;
if(s[x]=='?') sum+=max(0,g[x]);
}
addg(in[x]+len,-op);
for(int v:G[x])
Q[++tl]=v;
}
}
void mdf(int u,char c){
if(s[u]==c)return;
MDF(u,s[u],-1);
MDF(u,c,1);
char lst=s[u];
// cout<<"Sum "<<sum<<endl;
if(is1(lst) && !is1(c)) mdfanc(u,-1);
if(!is1(lst) && is1(c)) mdfanc(u,1);
// cout<<"nowsum "<<sum<<endl;
if(is0(lst) && !is0(c)) mdfsub(u,-1);
if(!is0(lst) && is0(c)) mdfsub(u,1);
s[u]=c;
}
void solve(int l,int r)
{
// cout<<"solve "<<l<<" "<<r<<endl;
len=0;
For(i,l,r)p[++len]=qu[i]; p[++len]=1;
sort(p+1,p+len+1,dfncmp);
Rep(i,len-1,1)p[++len]=lca(p[i],p[i+1]);
sort(p+1,p+len+1,dfncmp);
len=unique(p+1,p+len+1)-p-1;
For(i,1,len)G[p[i]].clear();
For(i,2,len){
vfa[p[i]]=lca(p[i-1],p[i]);
G[vfa[p[i]]].pb(p[i]);
}
For(i,1,len){
int u=p[i];
in[u]=i;
int x=u;
while(x!=vfa[u]) dw[x]=u,x=fa[x];
}
For(i,1,n)
up[i]=in[i]?i:up[fa[i]];
For(i,1,n)
if(!in[i]){
if(dw[i])ins(in[dw[i]],i);
else ins(in[up[i]]+len,i);
}
For(i,l,r){
mdf(qu[i],qc[i]);
printf("%lld\n",sum);
}
// clear
For(i,1,n){
if(!in[i]) f[i]+=tagf[bel[i]],g[i]+=tagg[bel[i]];
in[i]=bel[i]=dw[i]=up[i]=vfa[i]=0;
}
For(i,1,2*len){
tagf[i]=tagg[i]=0;
c0[i]=cg[i]=0;
For(j,-B,B)c[i][j]=0;
}
}
signed main()
{
//freopen("partial.in","r",stdin);
//freopen("partial.out","w",stdout);
n=read(),m=read();
scanf("%s",s+1);
For(i,2,n)fa[i]=read(),e[fa[i]].pb(i);
init();
predp(1);
For(i,1,n)
if(s[i]=='A') sum+=f[i];
else if(s[i]=='?') sum+=max(0,g[i]);
For(i,1,m)qu[i]=read(),cin>>qc[i];
B=sqrt(m);
inic();
for(int l=1,r;l<=m;l=r+1){
r=min(m,l+B-1);
solve(l,r);
}
return 0;
}
Details
Tip: Click on the bar to expand more detailed information
Test #1:
score: 100
Accepted
time: 3ms
memory: 28780kb
input:
5 3 AC??C 1 2 2 1 1 ? 4 A 2 ?
output:
4 3 3
result:
ok 3 lines
Test #2:
score: 0
Accepted
time: 0ms
memory: 36940kb
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 2768 2768 2772 2772 2772 2772 2772 2772 2772 2767 2767 2767 2767 2764 2766 2766 2769 2765 2761 2764 2767 2772 2772 2772 2772 2772 2772 2777 2777 2777 2777 2774 2771 2774 2782 2778 2778 2772 2768 2772 2772 2772 2772 2772 2774 2774 2778 2781 2781 2779 2782 2784 2787 2782 2786 2788 ...
result:
ok 1000 lines
Test #3:
score: -100
Runtime Error
input:
300000 300000 AAA?CA?AA?AC?A?CCA?AACCAAA???CA?ACCAACCCCAACAAA?CCAAAC?A?C??CC?C?C?CCCA?CAA?ACA??C?C?AC??CA??ACA?AA???CACAAA?CACCCCCCC?A?AAAAAC?AACCA????CCC?C?AAACCCAA?C???CCCC?AAACAAA???A?CAAC??A??A??CCCC??AA?C??ACA?AACAAA????CAA???AAAAACC?C?CCA?CCAA?AAC?CC?CA?A??CC??CCAC??C??????AAC?AA?AA?AAC?C??AAC...