NC24604. [USACO 2014 Ope G]Code Breaking
描述
输入描述
* Line 1: Two space-separated integers, N and M.
* Lines 2..N: Line i+1 contains a single integer p(i), denoting the
parent of node i in the tree (0 <= p(i) < i).
* Lines N+1..N+M: Line N+i describes the ith sequence known not to
occur in the code. The line will contain v(i) and s(i)
separated by a space, where v(i) is the starting node of the
sequence, and s(i) is a 5-digit string known not to occur
starting at v(i) and proceeding upward in the tree. It is
guaranteed that the root is at least 4 steps upward from v(i).
输出描述
* Line 1: A single integer giving the number of ruled-out
configurations, modulo 1234567.
示例1
输入:
6 2 0 1 2 3 3 4 01234 5 91234
输出:
19
C++11(clang++ 3.9) 解法, 执行用时: 547ms, 内存消耗: 24036K, 提交时间: 2020-03-07 11:37:45
#include<cstdio> #include<map> #include<algorithm> using namespace std; typedef map<int,int>T; const int N=20010,M=860000,MAXN=2100000,U=300010,P=1234567; int n,m,i,j,x,y,g[N],nxt[N],sub[M],right[M],ans;char ch[9]; T f[N];T::iterator k;int tmp[U],tag[MAXN];bool s[MAXN]; struct E{int x,y;E(){}E(int _x,int _y){x=_x,y=_y;}}q[U],e[U*2]; inline bool cmp(const E&a,const E&b){return a.x<b.x;} inline void up(int&a,int b){a=a+b<P?a+b:a+b-P;} inline void tag1(int x,int p){tag[x]=1LL*tag[x]*p%P;} inline void pb(int x){if(tag[x]!=1)tag1(x<<1,tag[x]),tag1(x<<1|1,tag[x]),tag[x]=1;} void build(int x,int a,int b){ if(a==b)return; tag[x]=1; int mid=(a+b)>>1; build(x<<1,a,mid),build(x<<1|1,mid+1,b); } void ins(int x,int a,int b,int c,int p){ if(a==b){ up(tag[x],p); s[x]=!!tag[x]; return; } pb(x); int mid=(a+b)>>1; if(c<=mid)ins(x<<1,a,mid,c,p);else ins(x<<1|1,mid+1,b,c,p); s[x]=s[x<<1]|s[x<<1|1]; } void change(int x,int a,int b,int c,int d,int p){ if(c<=a&&b<=d){tag1(x,p);return;} pb(x); int mid=(a+b)>>1; if(c<=mid)change(x<<1,a,mid,c,d,p); if(d>mid)change(x<<1|1,mid+1,b,c,d,p); } int ask(int x,int a,int b,int c){ if(a==b)return tag[x]; pb(x); int mid=(a+b)>>1; return c<=mid?ask(x<<1,a,mid,c):ask(x<<1|1,mid+1,b,c); } void dfs(int x,int a,int b,T&f){ if(!s[x])return; if(a==b){ if(tag[x])up(f[a<<4&1048575],tag[x]); tag[x]=s[x]=0; return; } pb(x); int mid=(a+b)>>1; dfs(x<<1,a,mid,f),dfs(x<<1|1,mid+1,b,f); s[x]=0; } inline void solve(){ int i,j,cnt=0,s=0; for(i=0;i<m;i++){ tmp[i]=0; for(j=sub[q[i].x];~j;j=sub[j])up(tmp[i],ask(1,0,M,j)); e[++cnt]=E(q[i].x,q[i].y); e[++cnt]=E(right[q[i].x],P-q[i].y); } sort(e+1,e+cnt+1,cmp); for(i=1;i<=cnt;i++){ if(i>1&&e[i].x>e[i-1].x)change(1,0,M,e[i-1].x,e[i].x-1,s); up(s,e[i].y); } for(i=0;i<m;i++)if(tmp[i])ins(1,0,M,q[i].x,1LL*q[i].y*tmp[i]%P); } int main(){ scanf("%d%d",&n,&m); for(i=2;i<=n;i++)scanf("%d",&x),nxt[i]=g[++x],g[x]=i; while(m--){ scanf("%d%s",&x,ch); for(y=j=0;j<5;j++)y=y<<4|(ch[j]-'0'+1); f[x+1][y]=P-1; } for(sub[0]=-1,right[0]=M,i=1;i<M;i++)for(j=0;;j++)if(i>>(j*4)&15){ sub[i]=i-(((i>>(j*4))&15)<<(j*4)); right[i]=i+(1<<(j*4)); break; } build(1,0,M); for(i=n;i;i--){ for(j=1;j<=10;j++)f[i][j<<16]=1; for(k=f[i].begin();k!=f[i].end();k++)ins(1,0,M,k->first,k->second); for(j=g[i];j;j=nxt[j]){ m=0; for(k=f[j].begin();k!=f[j].end();k++)q[m++]=E(k->first,k->second); solve(); } f[i].clear(); dfs(1,0,M,f[i]); } for(ans=i=1;i<=n;i++)ans=ans*10%P; up(ans,P-f[1][0]); return printf("%d",ans),0; }