zoukankan      html  css  js  c++  java
  • [atARC110E]Shorten ABC

    考虑令$a$、$b$和$c$分别对应1、2和3,那么每一次相当于令$x$和$y$变为$xoplus y$(要求$x e y$)

    根据异或的结合律,我们相当于将其划分为若干个区间求异或值

    (另外还有$x e y$的条件,归纳可证等价于要求区间异或值不为0且区间内字母不完全相等或仅有1个字母)

    为了保证每一种方案都不同,强制除了第一个以外的区间任意非空前缀异或值都不为0,否则可以把该前缀加入到上一个区间中(同时此时要保证了$x e y$的条件)

    令$f_{i}$表示前$i$个字母对应的方案数,考虑递推转移,设$j$为第一个异或前缀和等于$i$的,那么就转移到$(i,j)$,区间修改可以用差分来维护

    初始状态需要考虑一下,首先需要保证异或不为0,然后若所有字母完全相同(必然是奇数个),可以理解为最后$len-1$个字母是由下一段一个非空前缀补上来的,因此允许出现

    特别的,当所有字母都相同时答案为1,需要特判

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 #define N 1000005
     4 #define mod 1000000007
     5 int n,a[N],nex[N],lst[4],f[N];
     6 char s[N];
     7 void update(int l,int r,int x){
     8     f[l]=(f[l]+x)%mod;
     9     if (r+1<n)f[r+1]=(f[r+1]+mod-x)%mod;
    10 }
    11 int main(){
    12     scanf("%d%s",&n,s);
    13     for(int i=0;i<n;i++)a[i]=s[i]-'A'+1;
    14     bool flag=0;
    15     for(int i=1;i<n;i++)
    16         if (s[i]!=s[0])flag=1;
    17     if (!flag){
    18         printf("1");
    19         return 0;
    20     } 
    21     for(int i=1;i<n;i++)a[i]^=a[i-1];
    22     for(int i=0;i<4;i++)lst[i]=n;
    23     for(int i=n-1;i>=0;i--){
    24         nex[i]=lst[a[i]];
    25         lst[a[i]]=i;
    26     }
    27     for(int i=0;i<n;i++)
    28         if (a[i])update(i,i,1);
    29     for(int i=0;i<n;i++){
    30         if (i)f[i]=(f[i]+f[i-1])%mod;
    31         update(i+1,nex[i]-1,f[i]);
    32     }
    33     printf("%d",f[n-1]);
    34 } 
    View Code
  • 相关阅读:
    Django之搭建学员管理系统
    数据库查询操作(fetchone,fetchall)
    HTTP 方法:GET与 POST
    初识django框架
    Memcached的批量删除方案总结
    centos5.5 下面 lnmp环境遇到的小问题
    CentOS 5.5 --学习(1)
    HTTP请求方法及响应码详解(http get post head)
    codeigniter注意点
    htaccess 伪静态的规则
  • 原文地址:https://www.cnblogs.com/PYWBKTDA/p/14112042.html
Copyright © 2011-2022 走看看