题目链接:传送门
好题。
因为,所以珂以考虑暴莉枚举所有的x。
发现这里’x’取’a’或’b’,就能包含这一位选的情况,所以只用枚举两种就珂以了qwq。
暴莉枚举完后,得到一个确定的字符串。
然后考虑把这个问题转化成依赖性问题:
对于字符串上的每一位,建三个节点,分别表示选。
对于每个要求分类讨论。
(1)
即这个要求不可能被实现,珂以跳过。
(2)
也就是说,位置不能选
因为如果位置选,位置就一定要选,所以位置不能选。
考虑怎样强制让位置不选:
假设位置除了能选的另一个字符为,则从向连一条边。
这样如果选了,那么一定和在同一个强连通分量,是矛盾的。
所以就相当于强制选。
(3) 且
这是一般情况,按照普通的套路,对“若选A,则选B”和“若不选B,则不选A”建边即可qwq。
建完边就大莉跑就珂以了qwq
注:这题因为每个点有中情况,所以对字符的处理很臭。
毒瘤代码
#include<stdio.h>
#include<cstring>
#include<algorithm>
#include<math.h>
#include<vector>
#include<cctype>
#define re register int
#define rl register ll
#define lowbit(x) x&(-x)
using namespace std;
typedef long long ll;
int read() {
re x=0,f=1;
char ch=getchar();
while(ch<'0' || ch>'9') {
if(ch=='-') f=-1;
ch=getchar();
}
while(ch>='0' && ch<='9') {
x=10*x+ch-'0';
ch=getchar();
}
return x*f;
}
inline void write(int x) {
if(x>9) write(x/10);
putchar(x%10+'0');
}
inline char GetChar() {
char ch=getchar();
while(ch!='A' && ch!='B' && ch!='C') ch=getchar();
return ch;
}
namespace I_Love {
const int Size=300005;
int n,m,d,x[Size],y[Size];
char hx[Size],hy[Size];
char str[Size];
int pos[15];
void oper(int x) {
for(re i=1; i<=d; x>>=1,i++) {
if(x&1) {
str[pos[i]]='A';
} else {
str[pos[i]]='B';
}
}
}
int cnt,head[Size<<1];
struct Edge {
int v,next;
} w[Size<<2];
void AddEdge(int u,int v) {
w[++cnt].v=v;
w[cnt].next=head[u];
head[u]=cnt;
}
inline char getpre(char ch) {
if(ch=='A') return 'B';
return 'A';
}
inline char getnxt(char ch) {
if(ch=='C') return 'B';
return 'C';
}
inline int getid(int x,char ch) {
if(x>n) x-=n; if(x>n) x-=n;
if(ch=='A') return x;
if(ch=='B') return x+n;
return x+(n<<1);
}
inline char getother(int x,char ch) {
char now=str[x];
if(now=='A') return (int)'B'+'C'-ch;
if(now=='B') return (int)'A'+'C'-ch;
return (int)'A'+'B'-ch;
}
int tim,top,tot,dfn[Size],stk[Size],belong[Size],low[Size];
bool vis[Size];
void Tarjan(int x) {
dfn[x]=low[x]=++tim;
stk[++top]=x;
vis[x]=true;
for(int i=head[x]; i; i=w[i].next) {
int nxt=w[i].v;
if(!dfn[nxt]) {
Tarjan(nxt);
low[x]=min(low[x],low[nxt]);
} else if(vis[nxt]) {
low[x]=min(low[x],dfn[nxt]);
}
}
if(low[x]==dfn[x]) {
int y;
tot++;
while(y=stk[top--]) {
belong[y]=tot;
vis[y]=false;
if(x==y) return;
}
}
}
char ans[Size];
void Fujibayashi_Ryou() {
// freopen("game16.in","r",stdin);
// freopen("WA.txt","w",stdout);
n=read();
d=read();
scanf("%s",str+1);
m=read();
for(re i=1; i<=m; i++) {
x[i]=read();
hx[i]=GetChar();
y[i]=read();
hy[i]=GetChar();
}
int now=0;
for(re i=1; i<=n; i++) {
if(str[i]=='x') pos[++now]=i;
str[i]=toupper(str[i]);
}
int maxn=1<<d;
for(re i=0; i<maxn; i++) {
oper(i);
memset(head,0,sizeof(head)); cnt=0;
memset(belong,0,sizeof(belong)); tot=0;
memset(dfn,0,sizeof(dfn));
memset(low,0,sizeof(low));
for(re j=1; j<=m; j++) {
if(hx[j]==str[x[j]]) {
continue;
} else if(hy[j]==str[y[j]]) {
//不能让x[j]为hx[j]
AddEdge(getid(x[j],hx[j]),getid(x[j],getother(x[j],hx[j])));
} else {
//若x[j]选了hx[j],则y[j]要选hy[j]
AddEdge(getid(x[j],hx[j]),getid(y[j],hy[j]));
//若y[j]没选hy[j],则x[j]不选hx[j]
AddEdge(getid(y[j],getother(y[j],hy[j])),getid(x[j],getother(x[j],hx[j])));
}
}
for(re j=1; j<=n*3; j++) {
int id=j; if(id>n) id-=n; if(id>n) id-=n;
if(getid(id,str[id])!=j && !dfn[j]) {
Tarjan(j);
}
}
bool fail=false;
for(re j=1; j<=n; j++) {
int t1=getid(j,getpre(str[j]));
int t2=getid(j,getnxt(str[j]));
if(belong[t1]==belong[t2]) {
fail=true;
break;
}
if(belong[t1]<belong[t2]) {
ans[j]=getpre(str[j]);
} else {
ans[j]=getnxt(str[j]);
}
}
if(!fail) {
puts(ans+1);
return;
}
}
printf("-1");
}
}
int main() {
I_Love::Fujibayashi_Ryou();
return 0;
}
来源:https://blog.csdn.net/The_OIer/article/details/98984156