膜拜
时间限制:C/C++/Rust/Pascal 3秒,其他语言6秒
空间限制:C/C++/Rust/Pascal 512 M,其他语言1024 M
64bit IO Format: %lld

题目描述

给定一个长度为  且只由  ,  ,  三种小写英文字母组成的字符串  ,现在有  次操作。

每次操作都有两种可能:

  1. 给定一个整数  ,表示在  后插入一个  字符(插入字符后的下标依次顺延)

  2. 给定两个整数  ,查询  这个字符串区间中为  的子序列的数量。

如果一个字符串  能通过删除一些元素(可以不删也可以删完)得到字符串 ,那么字符串  就是字符串  的子序列。

输入描述:

第一行输入两个整数  表示字符串长度和询问次数。

为了减少输入量,你需要用备注中给出的随机数生成器来生成字符串  和  次操作。

第二行将输入三个范围在 unsigned int 内的整数  用于生成数据,具体生成代码将在备注中给出。

在执行给出生成代码的 gen() 函数后,字符串  将保存在名为 _s 的全局 char 类型的数组中,满足任意 

 次操作的操作类型将会保存在名为 _opt 的全局 int 类型的数组中,对于第  次操作:

如果 _opt[i] 的值为  ,那么操作中的整数  将保存在名为 _l[i] 的全局 int 类型的数组中。
如果 _opt[i] 的值为  ,那么操作中的整数  将分别保存在名为 _l[i] 和 _r[i] 的全局 int 类型的数组中。

输出描述:

我们如下定义  :

如果第  次操作为  号操作,那么 
如果第  次操作为  号操作,那么  即该次询问的答案。

为了减少输出量,你只需要输出所有  的异或和即可。

示例1

输入

复制
6 5
3488991686 1344677723 3466680979

输出

复制
10

说明

通过 gen() 生成得到的字符出  为 rorzoo 。

得到的  次操作分别是:

对  进行操作 ,得到 

对  进行操作 ,得到 

对  进行操作 ,得到 

对  进行操作 ,得到 

对  进行操作 ,得到 

最终答案为 

请注意常数因子对程序运行速度带来的影响。

备注:

unsigned int SA,SB,SC;
unsigned int rnd()
{
    SA^=SA<<16;
    SA^=SA>>5;
    SA^=SA<<1;
    unsigned int t=SA;
    SA=SB;SB=SC;
    SC^=t^SA;
    return SC;
}
int n,q;
char _s[1000005];
int _opt[1000005];
int _l[1000005],_r[1000005];
void gen()
{
    scanf("%d%d",&n,&q);
    scanf("%u%u%u",&SA,&SB,&SC);
    for(int i=1;i<=n;i++)
    {
        int si=rnd()%3;
        if(si==0) _s[i]='o';
        if(si==1) _s[i]='r';
        if(si==2) _s[i]='z';
    }
    for(int i=1;i<=q;++i)
    {
        _opt[i]=rnd()%2+1;
        if(_opt[i]==1)
            _l[i]=rnd()%n+1;
        else
        {
            int l=rnd()%n+1;
            int r=rnd()%n+1;
            if(l>r) std::swap(l,r);
            _l[i]=l;_r[i]=r;
        }
    }
}