# LOJ#2305. 「NOI2017」游戏

$n \leq 50000$的abcx序列，要你构造同样长一个ABC序列满足：如果这一位是a那就不能填A；如果是b不能填B；如果是c不能填C；否则随意。并满足$m \leq 100000$个限制：如果第$i$位填了$p$，那么第$j$位一定要填$q$。$x$个数不超过8.

1 #include<iostream>
2 #include<cstring>
3 #include<cstdio>
4 //#include<math.h>
5 //#include<set>
6 //#include<queue>
7 //#include<bitset>
8 //#include<vector>
9 #include<algorithm>
10 #include<stdlib.h>
11 using namespace std;
12
13 #define LL long long
15 {
16     char c; int s=0,f=1; while ((c=getchar())<'0' || c>'9') (c=='-') && (f=-1);
17     do s=s*10+c-'0'; while ((c=getchar())>='0' && c<='9'); return s*f;
18 }
19
20 //Pay attention to '-' , LL and double of qread!!!!
21
22 int n,m;
23 #define maxn 200011
24 struct Edge{int to,next;}edge[maxn<<1],edge2[maxn<<1]; int first[maxn],le=2,first2[maxn],le2;
25 void in(int x,int y) {Edge &e=edge[le]; e.to=y; e.next=first[x]; first[x]=le++;}
26 void in2(int x,int y) {Edge &e=edge2[le2]; e.to=y; e.next=first2[x]; first2[x]=le2++;}
27
29 bool insta[maxn];
30 void tarjan(int x)
31 {
32     dfn[x]=low[x]=++Time;
33     sta[++top]=x; insta[x]=1;
34     for (int i=first[x];i;i=edge[i].next)
35     {
36         Edge &e=edge[i];
37         if (!dfn[e.to]) tarjan(e.to),low[x]=min(low[x],low[e.to]);
38         else if (insta[e.to]) low[x]=min(low[x],dfn[e.to]);
39     }
40     if (dfn[x]==low[x])
41     {
42         tot++;
43         while (sta[top]!=x) insta[sta[top]]=0,bel[sta[top]]=tot,top--;
44         insta[sta[top]]=0,bel[sta[top]]=tot,top--;
45     }
46 }
47 void tag(int x)
48 {
49     cho[x]=2;
50     for (int i=first2[x];i;i=edge2[i].next)
51     {
52         Edge &e=edge2[i];
53         if (!cho[e.to]) tag(e.to);
54     }
55 }
56
57 void clear()
58 {
59     memset(first,0,sizeof(first)); le=2;
60     memset(first2,0,sizeof(first2)); le2=2;
61     tot=Time=top=0;
62     memset(bel,0,sizeof(bel));
63     memset(dfn,0,sizeof(dfn));
64     memset(low,0,sizeof(low));
65     memset(opp,0,sizeof(opp));
66     memset(cho,0,sizeof(cho));
67     memset(du,0,sizeof(du));
68 }
69
70 char s[maxn]; int pos[11],lp=0;
71 struct Eve{int x1,y1,x2,y2;}eve[maxn];
72 int pp[maxn][2];
73
74 int getnum(char c) {return c=='A'?0:(c=='B'?1:2);}
75 char getch(int x) {return x==0?'A':(x==1?'B':'C');}
76
77 bool END;
78 bool work()
79 {
80 //    cout<<(s+1)<<endl;
81     clear();
82     for (int i=1;i<=n;i++) if (s[i]=='a') {pp[i][0]=1; pp[i][1]=2;}
83     else if (s[i]=='b') {pp[i][0]=0; pp[i][1]=2;}
84     else if (s[i]=='c') {pp[i][0]=0; pp[i][1]=1;}
85     for (int i=1;i<=m;i++)
86     {
87         int x=eve[i].x1,y=eve[i].x2,xx=eve[i].y1,yy=eve[i].y2;
88         for (int j=0;j<=1;j++) if (pp[x][j]==xx)
89         {
90             bool flag=0;
91             for (int k=0;k<=1;k++) if (pp[y][k]==yy) in(x+j*n,y+k*n),in(y+(k^1)*n,x+(j^1)*n),flag=1;
92             if (!flag) in(x+j*n,x+(j^1)*n);
93         }
94     }
95 //    for (int i=1;i<=4;i++)
96 //        for (int j=first[i];j;j=edge[j].next)
97 //            cout<<i<<' '<<edge[j].to<<endl;cout<<endl;
98
99     for (int i=1;i<=2*n;i++) if (!dfn[i]) tarjan(i);
100     for (int i=1;i<=n;i++) if (bel[i]==bel[i+n]) return 0;
101
102     for (int i=1;i<=n;i++) opp[bel[i]]=bel[i+n],opp[bel[i+n]]=bel[i];
103     for (int i=1;i<=2*n;i++)
104         for (int j=first[i];j;j=edge[j].next)
105         {
106             Edge &e=edge[j];
107             if (bel[i]!=bel[e.to]) in2(bel[e.to],bel[i]),du[bel[i]]++;
108         }
109 //    for (int i=1;i<=4;i++) cout<<bel[i]<<' ';cout<<endl;
111     for (int i=1;i<=tot;i++) if (!du[i]) que[tail++]=i;
113     {
115         if (!cho[u]) {cho[u]=1; tag(v);}
116         for (int i=first2[u];i;i=edge2[i].next)
117         {
118             Edge &e=edge2[i];
119             du[e.to]--; if (!du[e.to]) que[tail++]=e.to;
120         }
121     }
122     for (int i=1;i<=n;i++) if (cho[bel[i]]==1) putchar(getch(pp[i][0])); else putchar(getch(pp[i][1]));
123     return 1;
124 }
125
126 void dfs(int x)
127 {
128     if (END) return;
129     if (x>lp) {if (work()) END=1; return;}
130     s[pos[x]]='a'; dfs(x+1); if (END) return;
131     s[pos[x]]='b'; dfs(x+1);
132 }
133
134 int main()
135 {
137     scanf("%s",s+1);
139     {
141         char c; while ((c=getchar())<'A' || c>'Z');
142         eve[i].y1=getnum(c);