首页 > 其他分享 >Codeforces 1704 F Colouring Game 题解 (结论,SG函数)

Codeforces 1704 F Colouring Game 题解 (结论,SG函数)

时间:2023-01-10 11:11:57浏览次数:58  
标签:1704 RB int 题解 rep Codeforces Alice BR sg

题目链接

首先看R和B的数量不等的情况(很多博弈题都是先比较两种物品的数量,相等的情况再用SG函数之类的技巧),结论是R多Alice必赢,B多Bob必赢。证明:来看R比B多的情况,定义两人的"差距"为当前R的数量减B的数量。发现Alice操作只可能让差距不变或变小,Bob操作只可能让差距不变或变大。定义"一轮游戏"为Alice先操作一次,Bob再操作一次的过程。如果一轮开始前还有"RB"或"BR",那么Alice就随便找一个RB或BR涂了,这一轮差距就肯定不会变小,Alice仍然保持领先;如果没有RB或BR,就看有没有RW或WR,如果有就随便找一个涂了,由于此时没有RB、BR所以Bob也只能涂BW和WB,因此差距仍然不会减小;只有RR的情况是不存在的,除非整个序列全是R,但是这种情况Alice本来就会赢。对于B比R多的情况也是类似(Alice第一次操作后B显然还比R多,所以就变成和上面一样的情况了)。

R和B相等的情况,两人都只能涂RB或BR,否则会导致R和B不相等,根据上面的结论操作这步的人就输了。所以问题变成:两个人每次可以挑相邻的两个RB或BR涂白,不能操作的人输。把序列分成若干段,每段都是极长的RBRBRB交错的区间。被涂的位置肯定是被完全包含在某个段内部,不可能横跨两个段的,因为这样不可能是RB或BR。发现每一段的内部都构成了一个公平的有向图游戏,可以对每一段求SG函数再异或起来得到答案。一个长为i的段的SG函数为:\(sg_i=mex_{l+r=i-1}(sg_l\bigoplus sg_r)\),其中\(\bigoplus\)表示异或。这玩意儿看上去像卷积,但其实不太能用多项式技巧求。正确的求法居然是:sg值除了前几项,后面的均以34为循环节,所以暴力求出前若干项(比如1000)就行了。真的是很无聊(不知道这题怎么过cf审核的),但是也要了解一下,防止以后再出现这种题。

点击查看代码
#include <bits/stdc++.h>

#define rep(i,n) for(int i=0;i<n;++i)
#define repn(i,n) for(int i=1;i<=n;++i)
#define LL long long
#define pii pair <int,int>
#define fi first
#define se second
#define mpr make_pair
#define pb push_back

void fileio()
{
  #ifdef LGS
  freopen("in.txt","r",stdin);
  freopen("out.txt","w",stdout);
  #endif
}
void termin()
{
  #ifdef LGS
  std::cout<<"\n\nEXECUTION TERMINATED";
  #endif
  exit(0);
}

using namespace std;

int sg[500010];

int dfs(int pos)
{
  if(sg[pos]>-1) return sg[pos];
  if(pos<2) return sg[pos]=0;
  map <int,int> mp;
  rep(i,pos-1)
  {
    int l=i,r=pos-l-2;
    int val=dfs(l)^dfs(r);
    mp[val]=1;
  }
  rep(i,1000) if(mp.find(i)==mp.end()) return sg[pos]=i;
}

int t,n;
string s;
char c[500010];

int main()
{
  fileio();

  rep(i,1005) sg[i]=-1;
  dfs(1000);
  for(int i=1001;i<=500005;++i) sg[i]=sg[i-34];
  cin>>t;
  rep(tn,t)
  {
    scanf("%d%s",&n,c);s=c;
    int cr=0,cb=0;
    rep(i,n) if(s[i]=='R') ++cr;else ++cb;
    if(cr>cb) puts("Alice");
    else if(cb>cr) puts("Bob");
    else
    {
      int ans=0;
      rep(i,n)
      {
        int p=i;
        while(p+1<n&&s[p+1]!=s[p]) ++p;
        ans^=sg[p-i+1];i=p;
      }
      puts(ans ? "Alice":"Bob");
    }
  }

  termin();
}

标签:1704,RB,int,题解,rep,Codeforces,Alice,BR,sg
From: https://www.cnblogs.com/legendstane/p/codeforces-1704-f-Colouring-Game-codeton-round-solut

相关文章

  • Educational Codeforces Round 114 D(搜索剪枝)
    D.TheStrongestBuild题目大意:给定n个位置,每个位置有c\({_i}\)个可选能力值(能力值升序给出即a\({_1}\)<a\({_2}\)<a\({_3}\)<...<a\({_{ci}}\)),你可以在每个......
  • CodeForces - 510C Fox And Names
    CodeForces-510CFoxAndNames题解:建图+拓扑排序首先题目想让你按照给定的字符串修改字母表的字母序,我们很容易想到拓扑排序,但是这怎么建图?实际上对于两个输入的字......
  • 2023-2-训练赛5 题解
    Buctoj训练赛5题解(C++)A、统计单词数该题目考查对string字符串的灵活运用初步观察题目,可将解题步骤分为大致四个模块输入两行字符串由于题目要求不区分大小写,故将......
  • Namomo Winter Camp D3 Div2 简易题解
    题目提交链接ProblemK.KotlinIsland首先不用考虑描边(那样和不画这条边是一样的)。那么剩下的就是在长度和宽度内枚举了。显然可以知道长宽最多画\((n-1)/2\)和......
  • 十二省联考 2019 题解
    Day1B字符串问题朴素的想法是,建一张\(n_a+n_b\)个点的有向图\(G\)。对于一个支配关系\((x,y)\),从\(x\)向\(y+n_a\)连边。此外,枚举\(1\lei\len_b\),对于每个......
  • 1.9寒假集训-进阶训练赛(五)A-M题解
    前五题网上都有不写了需要注意的是第四题是给定密钥和密文要把它加密算是一个逆过程看了半天都没读懂样例 第六题应该也有但是我写一下因为学校oj这边空间给的是1......
  • Educational Codeforces Round 141 (Rated for Div. 2) Different Arrays
    Problem-D-Codeforces题意:给一个长度为n的数组a,下标从2到n-1,每个位置执行一次操作操作:设操作位置为i,$a_{i-1}+=a_i,a_{i+1}-=a_i$,或者$a_{i-1}-=a_i,a_......
  • HDU-3949 XOR 题解报告
    题目地址题意:从一个序列中取任意个元素进行异或,求能异或出的所有数字中的第k小。分析:性质:一个线性基异或上另一个不同的线性基,并作为自己的新值,这并不改变整个线性......
  • Educational Codeforces Round 141 (Rated for Div. 2) A-E
    比赛链接A题意给一个数组\(a\),要求重排列以后\(a[i]\neqa[1,i-1]\),其中\(a[1,i-1]\)是前\(i-1\)项和。如果无解则输出NO;否则,给出一个合法的重排列后的\(a......
  • 【CF802O】April Fools' Problem (hard) 题解 (线段树模拟费用流)
    线段树模拟费用流。LG传送门。SolutionPart1根据题面,显然想到此题是费用流。建图方式亦是显然:\(S\rightarrowi\),流量为\(1\),费用为\(a_i\);\(i\rightarrowT_0\)......