zoukankan      html  css  js  c++  java
  • Codeforces1037G A Game on Strings 【SG函数】【区间DP】

    题目分析:

    一开始没想到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 }
  • 相关阅读:
    网络爬虫基础练习
    词频统计预处理
    将博客搬至CSDN
    内核探测工具systemtap简介(转)
    常用汉字的Unicode码表
    随机生成登录时的验证码图片
    response中用outputstream输出中文问题
    ServletContext读取web应用中的资源文件
    ServletContext
    URL描述web资源访问流程
  • 原文地址:https://www.cnblogs.com/Menhera/p/9648350.html
Copyright © 2011-2022 走看看