题目分析:

一开始没想到SG函数,其它想到了就开始敲,后来发现不对才发现了需要SG函数。

把每个字母单独提出来,可以发现有用的区间只有两个字母之间的区间和一个位置到另一个字母的不跨越另一个相同字母的位置。

对于这些区间,用区间DP处理出来答案,合并答案的时候用SG函数。

代码:

  1 #include<bits/stdc++.h>
  2 using namespace std;
  3
  4 const int maxn= 100050;
  5
  6 int n,q;
  7 char str[maxn];
  8 int pre[26][maxn],suf[26][maxn];
  9 int arr[26][maxn],ar[26][maxn];
 10 int Pf[26][maxn],Sf[26][maxn];
 11
 12 int solve(int,int,int);
 13
 14 int hd(int k,int l,int r,int dep){
 15     if(ar[k][l]) return Sf[k][l];
 16     else {
 17         ar[k][l]=1,Sf[k][l] = solve(l,r,dep+1);
 18         return Sf[k][l];
 19     }
 20 }
 21 int pd(int k,int r,int l,int dep){
 22     if(arr[k][r]) return Pf[k][r];
 23     else{
 24         arr[k][r] = 1,Pf[k][r] = solve(l,r,dep+1);
 25         return Pf[k][r];
 26     }
 27 }
 28
 29 int app[maxn][28];
 30 int solve(int l,int r,int dep){
 31     if(l > r) return 0;
 32     if(l == r) return 1;
 33     for(int k=0;k<=26;k++) app[dep][k] = 0;
 34     for(int k=0;k<26;k++){
 35         int pv = suf[k][l],sv = pre[k][r];
 36         if(pv > r || sv < l || pv == -1 || sv == -1) continue;
 37         int ans = Pf[k][sv]^Pf[k][pv];
 38         if(pre[k][r] != r) ans ^= pd(k,r,sv+1,dep);
 39         if(suf[k][l] != l) ans ^= hd(k,l,pv-1,dep);
 40         app[dep][ans] = 1;
 41     }
 42     for(int i=0;i<=26;i++) if(app[dep][i] == 0) return i;
 43 }
 44
 45 void init(){
 46     for(int i=0;i<n;i++){
 47         if(i-1>=0&&pre[str[i]-'a'][i-1]!=-1){
 48             int k = str[i]-'a';
 49             if(pre[k][i-1]+1>i-1) Pf[k][i]=Pf[k][pre[k][i-1]];
 50             else Pf[k][i]=Pf[k][pre[k][i-1]]^Pf[k][i-1];
 51             arr[k][i] = 1;
 52         }
 53         for(int k=0;k<26;k++){
 54             if(pre[k][i] == -1) continue;
 55             if(arr[k][i]) continue;
 56             if(pre[k][i] != i) Pf[k][i] = solve(pre[k][i]+1,i,0);
 57             arr[k][i] = 1;
 58         }
 59     }
 60     for(int i=n-1;i>=0;i--){
 61         if(i+1<n&&suf[str[i]-'a'][i+1]!=-1){
 62             int k = str[i]-'a';
 63             if(i+1 > suf[k][i+1]-1) Sf[k][i]=Sf[k][suf[k][i+1]];
 64             else Sf[k][i]=Sf[k][suf[k][i+1]]^Sf[k][i+1];
 65             ar[k][i] = 1;
 66         }
 67         for(int k=0;k<26;k++){
 68             if(suf[k][i] == -1) continue;
 69             if(ar[k][i]) continue;
 70             if(suf[k][i] != i) Sf[k][i] = solve(i,suf[k][i]-1,0);
 71             ar[k][i] = 1;
 72         }
 73     }
 74 }
 75
 76 void read(){
 77     scanf("%s",str);
 78     scanf("%d",&q);
 79     n = strlen(str);
 80     for(int k=0;k<26;k++){for(int i=0;i<n;i++) pre[k][i] = suf[k][i] = -1;}
 81     for(int i=0;i<n;i++)pre[str[i]-'a'][i] = i,suf[str[i]-'a'][i] = i;
 82     for(int k=0;k<26;k++){
 83         for(int i=1;i<n;i++) if(pre[k][i]==-1) pre[k][i] = pre[k][i-1];
 84         for(int i=n-2;i>=0;i--) if(suf[k][i]==-1) suf[k][i] = suf[k][i+1];
 85     }
 86 }
 87
 88 void work(){
 89     for(int i=1;i<=q;i++){
 90         int l,r; scanf("%d%d",&l,&r);
 91         int flag = solve(l-1,r-1,0);
 92         if(flag) puts("Alice");
 93         else puts("Bob");
 94     }
 95 }
 96
 97 int main(){
 98     //freopen("1.in","r",stdin);
 99     //freopen("1.out","w",stdout);
100     read();
101     init();
102     work();
103     return 0;
104 }

转载于:https://www.cnblogs.com/Menhera/p/9648350.html

Codeforces1037G A Game on Strings 【SG函数】【区间DP】相关推荐

  1. 《算法竞赛进阶指南》数论篇(3)-组合计数,Lucas定理,Catalan数列,容斥原理,莫比乌斯反演,概率与数学期望,博弈论之SG函数

    文章目录 组合计数 例题:Counting swaps Lucas定理 Cnm≡Cnmodpmmodp∗Cn/pm/p(modp)C_n^m\equiv C_{n\ mod\ p}^{m\ mod\ ...

  2. Trie树合并 + SG函数 ---- BZOJ4730. Alice和Bob又在玩游戏(动态开点Trie 树上全局异或标记 + 合并 + 博弈论)

    题目大题 题目大意: 解题思路: 首先我们对于子树u的SG函数为SG函数为SG函数为 ⨁是异或和\bigoplus是异或和⨁是异或和 SG[u]=mex{⨁w∈(w的父亲在u到v的路径上)SG[w]∣ ...

  3. 点分治问题 ----------- P3727 曼哈顿计划E[点分治+博弈SG函数打表找规律]

    题目链接 解题思路: 1.首先对于每个操作我们实际上是一个博弈问题 对于k=1的操作就是很基础的NIM游戏就是找到一条链的异或和为0 对于k=2的操作通过达打表找规律: 如果s是奇数那么偶数的SG函数 ...

  4. BZOJ 1874: [BeiJing2009 WinterCamp]取石子游戏(SG函数)

    Time Limit: 5 Sec  Memory Limit: 162 MB Submit: 871  Solved: 365 [Submit][Status][Discuss] Descripti ...

  5. 一类SG函数递推性质的深入分析——2018ACM陕西邀请赛H题

    题目描述 定义一种有根二叉树\(T(n)\)如下: (1)\(T(1)\)是一条长度为\(p\)的链: (2)\(T(2)\)是一条长度为\(q\)的链: (3)\(T(i)\)是一棵二叉树,它的左子 ...

  6. hdu1848(sg函数打表)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1848 题意:中文题诶- 思路:直接sg函数打表就好了 代码: 1 #include <iostr ...

  7. AtCoder AGC043C Giant Graph (图论、SG函数、FWT)

    题目链接 https://atcoder.jp/contests/agc043/tasks/agc043_c 题解 场上感觉没啥思路就放弃了,场下想了十几分钟发现是水题,血亏...(只能怪自己计数水平 ...

  8. (转)博弈问题与SG函数

    博弈问题 若你想仔细学习博弈论,我强烈推荐加利福尼亚大学的Thomas S. Ferguson教授精心撰写并免费提供的这份教材,它使我受益太多.(如果你的英文水平不足以阅读它,我只能说,恐怕你还没到需 ...

  9. NIM博弈+SG函数求解

    ICG 给定一个有向无环图和一个起始顶点上的一枚棋子,两名选手交替的将这枚棋子沿有向边进行移动,无法移动者判负. 这个游戏可以认为是所有 Impartial Combinatorial Games 的 ...

  10. SG函数和SG定理(Sprague_Grundy)

    一.必胜点和必败点的概念 P点:必败点,换而言之,就是谁处于此位置,则在双方操作正确的情况下必败.        N点:必胜点,处于此情况下,双方操作均正确的情况下必胜. 必胜点和必败点的性质:    ...

最新文章

  1. C#和Javascript间互转的Xxtea加解密
  2. C++ 用vector创建数组对象
  3. Docker仓库搭建
  4. webpack打包之clean-webpack-plugin插件 默认下载4.0.0版本的踩坑记录
  5. LPWSTR 类型的实参与const.char *类型形参不兼容
  6. 面向对象的相关面试题
  7. can总线报文是固定的吗_新能源汽车CAN总线Bus Off处理流程
  8. java jdk安装与环境变量配置
  9. linux 网络 PING IP可以通,ping域名ping不通
  10. html兄弟选择器怎么用,兄弟选择器 - 选择后面相邻的所有兄弟元素 - css3普通选择器...
  11. [转帖] 启动多个Tomcat 需要修改的端口
  12. CloudStack 4.4学习总结之注册ISO
  13. Python学习笔记之 高级变量类型 列表,元组,字典,字符串的相关常用 操作
  14. 中国科学报:吴文俊的数字之舞
  15. Linux下文件名乱码的解决方法
  16. Tensorflow入门到实战五(卷积神经网络)
  17. android手机对网络请求抓包
  18. 微信小程序 - <textarea> 多行文本输入框 placeholder 属性换行显示文字(适用于 vant-weapp 的 Field 输入框文本域组件 van-field)样式修改的详细教程
  19. kali ifconfig没有wlan0的解决方法
  20. 机器视觉系统图像采集卡功能特点及应用场景介绍

热门文章

  1. 拓端tecdat|R 语言绘制功能富集泡泡图
  2. php excel引入tp,TP5引用PHPExcel实现导入导出功能
  3. ECMAScript 学习笔记03
  4. python类基础知识
  5. python中的[1:]、[::-1]、X[:,m:n]和X[1,:]
  6. 如何应对训练的神经网络不工作?
  7. Python Numpy模块函数np.c_和np.r_学习使用
  8. python实现找到给定列表中满足给定和的所有子列表,元素可重复使用
  9. 决用 Anaconda 完美解 Python2 和 python3 共存问题
  10. 2021-08-22 过滤器实现登录权限拦截