题解:P10653 「ROI 2017 Day 2」存储器
题意
有两个由 + 和 - 组成的字符串
题解
我们从特殊性质开始考虑:-。
对于 - 构成的串,我们必须想办法将其翻转。
首先有一个接近 + 组成的串,判断其右边的串是否能翻转。若能,则将这段串右边、右边的右边的串都删掉,并增加这段串的长度。最后,若不能操作时仍有 -,则输出 No,否则输出 Yes,代码如下:
void link(int u,int v){
nxt[u]=v, pre[v]=u;
}
bool check(){
s[n+1]=t[n+1]='\0';
cnt=0;
if(s[1]=='-') cnt=1, siz[1]=0;
int tmp=1;
rep(i, 2, n+1){
if(s[i]!=s[i-1]) siz[++cnt]=tmp, tmp=1;
else ++tmp;
}
if(cnt%2==0) siz[++cnt]=0;
rep(i, 1, cnt-1) link(i, i+1);
nxt[cnt]=0;
while(nxt[1]){
bool flag=0;
for(int i=1, j; nxt[i];){
j=nxt[nxt[i]];
if(siz[j]>siz[nxt[i]] || siz[i]>siz[nxt[i]]){
siz[i]+=siz[j]+siz[nxt[i]];
link(i, nxt[j]);
flag=1;
}
i=j;
}
if(!flag) break;
}
return !nxt[1];
}
这段代码在随机数据下的复杂度应该是 --+--+--+-++ 的串时,复杂度退化为 + 串,再进行判断。这样就变成
j=nxt[nxt[i]];
if(siz[j]>siz[nxt[i]] || siz[i]>siz[nxt[i]]){
siz[i]+=siz[j]+siz[nxt[i]];
link(i, nxt[j]);
flag=1;
if(pre[i]) i=pre[pre[i]];
} else i=j;
接下来正解就水到渠成啦!!对于
需要注意的一点是,若对于 No 就好。
于是,这道题就做完了。
Code
const int N=1e6+7;
int n;
char s[N], t[N];
namespace sub{
int n;
char s[N], t[N];
int siz[N], pre[N], nxt[N], cnt;
void link(int u,int v){
nxt[u]=v, pre[v]=u;
}
bool check(){
s[n+1]=t[n+1]='\0';
// cout<<s+1<<' '<<t+1<<endl;
if(t[1]=='-'){
rep(i, 1, n)
s[i]=s[i]=='-'?'+':'-';
}
cnt=0;
if(s[1]=='-') cnt=1, siz[1]=0;
int tmp=1;
rep(i, 2, n+1){
if(s[i]!=s[i-1]) siz[++cnt]=tmp, tmp=1;
else ++tmp;
}
if(cnt%2==0) siz[++cnt]=0;
rep(i, 1, cnt-1) link(i, i+1);
nxt[cnt]=0;
while(nxt[1]){
bool flag=0;
for(int i=1, j; nxt[i];){
j=nxt[nxt[i]];
if(siz[j]>siz[nxt[i]] || siz[i]>siz[nxt[i]]){
siz[i]+=siz[j]+siz[nxt[i]];
link(i, nxt[j]);
flag=1;
if(pre[i]) i=pre[pre[i]];
} else i=j;
}
if(!flag) break;
}
return !nxt[1];
}
}
void run(){
cin>>s+1>>t+1;
n=strlen(s+1);
for(int i=1; i<=n;){
int pos=i;
while(pos<=n && t[pos]==t[i]) ++pos;
if(i!=1 && s[i]==s[i-1] || pos!=n+1 && s[pos]==s[pos-1]){
cout<<"No\n";
return;
}
sub::n=pos-i;
rep(j, 1, pos-i)
sub::s[j]=s[i+j-1], sub::t[j]=t[i+j-1];
if(!sub::check()){
cout<<"No\n";
return;
}
rep(j, i, pos-1) s[j]=t[j];
i=pos;
}
cout<<"Yes\n";
}
signed main(){
ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
int t; cin>>t;
while(t--) run();
}
都看到这里了,点个赞再走呗。