题解:P11207 「Cfz Round 9」Rose

可以考虑把字符串 \(s\)\(t\)\(s_1 t_1 s_2 t_2 \dots s_n t_n\) 拼接,记为 \(a\)。为了方便表述,这里分别把 PVW 表示为 012

Subtask 0

我会暴力!可以直接在 \(a\) 上进行 dfs,复杂度为 \(O(3^{2n})\)

Subtask 1

我会找性质!注意到答案只有可能是 \(0,1,2\),因为在最坏情况下,只要 \(2\) 次操作把 \(a_1,a_2,a_3\) 改成互不相同的数就行了。

首先我们可以 \(O(n)\) 判断答案是否为 \(0\)。接下来判断答案是否为 \(1\),我们可以枚举修改哪个位置,再扫一遍 \(a\) 就可以了。剩下的情况的答案必然为 \(2\)。总复杂度为 \(O(n^2)\)

Subtask 4

考虑在判断答案是否为 \(1\) 的过程上优化,可以发现答案为 \(1\) 时,设获胜的位置为 \(i\)\(s_{0/1/2}\) 表示 \(a_1 \sim a_i\)\(0,1,2\) 出现的个数,则 \(3 \mid i\)\(\{s0,s1,s2\}=\{\frac{i}{3}-1,\frac{i}{3},\frac{i}{3}+1\}\)。于是我们就记录每个 \(a_i\) 最后出现的位置。

但是,如果把某个位置修改后,自己比对手先赢,就会出现问题。于是,我们设 \(lst_{i,j}\) 表示最前的把 \(i\) 改为 \(j\) 且不会出现这种情况的位置。每次出现 \(3 \mid i\)\(\{s0,s1,s2\}=\{\frac{i}{3}-1,\frac{i}{3},\frac{i}{3}+1\}\) 时,如果 \(i\) 为偶数,就把操作一次会赢的 \(lst_{i,j}\) 清空,否则若 \(i\) 为奇数,如果存在符合的 \(lst_{i,j}\),答案就为 \(1\)

最后,如果在自己在 \(pos\) 位置不做操作就已经赢了,还需要满足 \(lst_{i,j} \leq pos\)

这些都可以 \(O(n)\) 维护。

代码:(这里的 \(lst_{i,j}\) 进行了状态压缩)

#include<bits/stdc++.h>
using namespace std;
#define int long long
#define flush() fwrite(obuf,1,O-obuf,stdout)
#define putchar(x) ((O==obuf+(1<<21))&&(flush(),O=obuf)),*O++=x
char buf[1<<23],*p1=buf,*p2=buf,obuf[1<<23],*O=obuf;
#define getchar() (p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++)
inline int read() {
    register int x=0,f=1;register char ch=getchar();
    while(!isdigit(ch)){if(ch=='-') f=-1;ch=getchar();}
    while(isdigit(ch)) x=x*10+(ch^48),ch=getchar();
    return x*f;
}
inline void write(register int x){
    if(x<0) putchar('-'),x=-x;
    if(x>9) write(x/10);
    putchar((x%10)^48);
}
struct Flush{
    ~Flush(){flush();}
}_;
#define N 100010
int t,n,a[N*2],ans;
signed main(){
    int T;
    cin>>t;
    T=t;
    while(t--){
        ans=556676;
        cin>>n;
        for(int i=1;i<=2*n;i++){
            a[i]=0;
        }
        for(int i=1;i<=n;i++){
            char c;
            cin>>c;
            if(c=='P'){
                a[2*i-1]=0;
            }
            else{
                if(c=='V'){
                    a[2*i-1]=1;
                }
                else{
                    a[2*i-1]=2;
                }
            }
        }
        for(int i=1;i<=n;i++){
            char c;
            cin>>c;
            if(c=='P'){
                a[2*i]=0;
            }
            else{
                if(c=='V'){
                    a[2*i]=1;
                }
                else{
                    a[2*i]=2;
                }
            }
        }
            int s[3]={};
            for(int i=1;i<=2*n;i++){
                s[a[i]]++;
                if(s[0]==s[1]&&s[1]==s[2]){
                    if(i%2==1){
                        ans=0;
                    }
                    break;
                }
            }
            if(ans==0){
                cout<<0<<endl;
                continue;
            }
            s[0]=s[1]=s[2]=0;
            int pos=2*n;
            int lst[9]={};
            for(int i=1;i<=2*n;i++){
                if(i<=pos){
                    lst[a[i]*3+0]=lst[a[i]*3+1]=lst[a[i]*3+2]=i;
                }
                s[a[i]]++;
                if(i%2==0){
                    if(s[0]==s[1]&&s[0]==s[2]){
                        pos=min(pos,i);
                        continue;
                    }
                    if(s[0]==s[1]-1&&s[1]==s[2]-1){
                        lst[6]=0;
                    }
                    if(s[0]==s[2]-1&&s[2]==s[1]-1){
                        lst[3]=0;
                    }
                    if(s[1]==s[0]-1&&s[0]==s[2]-1){
                        lst[7]=0;
                    }
                    if(s[1]==s[2]-1&&s[2]==s[0]-1){
                        lst[1]=0;
                    }
                    if(s[2]==s[0]-1&&s[0]==s[1]-1){
                        lst[5]=0;
                    }
                    if(s[2]==s[1]-1&&s[1]==s[0]-1){
                        lst[2]=0;
                    }
                }
                else{
                    if(s[0]==s[1]-1&&s[1]==s[2]-1){
                        if(lst[6]&&lst[6]<=pos){
                            ans=1;
                            break;
                        }
                    }
                    if(s[0]==s[2]-1&&s[2]==s[1]-1){
                        if(lst[3]&&lst[3]<=pos){
                            ans=1;
                            break;
                        }
                    }
                    if(s[1]==s[0]-1&&s[0]==s[2]-1){
                        if(lst[7]&&lst[7]<=pos){
                            ans=1;
                            break;
                        }
                    }
                    if(s[1]==s[2]-1&&s[2]==s[0]-1){
                        if(lst[1]&&lst[1]<=pos){
                            ans=1;
                            break;
                        }
                    }
                    if(s[2]==s[0]-1&&s[0]==s[1]-1){
                        if(lst[5]&&lst[5]<=pos){
                            ans=1;
                            break;
                        }
                    }
                    if(s[2]==s[1]-1&&s[1]==s[0]-1){
                        if(lst[2]&&lst[2]<=pos){
                            ans=1;
                            break;
                        }
                    }
                }
            }
            if(ans==1){
                cout<<1<<endl;
            }
            else{
                cout<<2<<endl;
            }
    }
    return 0;
}
posted @ 2024-10-22 20:53  CJZJC  阅读(6)  评论(0编辑  收藏  举报