放一个常数巨大不能通过的做法

首先子序列信息显然可以动态 dp。

然后有插入操作,于是显然得用平衡树来维护区间信息。

打的 WBLT,然后结果实测不加平衡措施还更快???(除掉 S=0 外,均有数据随机)

struct Info{ullt O,R,Z,OR,RZ,ORZ;__always_inline friend Info operator+(Info a,Info b){return Info{a.O+b.O,a.R+b.R,a.Z+b.Z,a.OR+b.OR+a.O*b.R,a.RZ+b.RZ+a.R*b.Z,a.ORZ+b.ORZ+a.O*b.RZ+a.OR*b.Z};}};
struct Seg
{
    Seg*L,*R;uint len;Info v;
    Seg():L(NULL),R(NULL),len(1),v({1,0,0,0,0,0}){}
    Seg(Info v):L(NULL),R(NULL),len(1),v(v){}
    Seg(chr*bgn,chr*end):L(NULL),R(NULL),len(end-bgn){
        if(len>1)L=new Seg(bgn,bgn+(len>>1)),R=new Seg(bgn+(len>>1),end),v=L->v+R->v;
        else v={*bgn=='o',*bgn=='r',*bgn=='z',0,0,0};
    }
}*S;
voi insert(Seg*S,uint p)
{
    if(S->len==1){S->L=new Seg(S->v),S->v=S->v+(S->R=new Seg())->v,S->len=2;return;}
    uint LEN=S->L->len;
    p<LEN?insert(S->L,p):insert(S->R,p-LEN);S->len++,S->v=S->L->v+S->R->v;
}
Info find(Seg*S,uint l,uint r)
{
    while(l||r<S->len){
        uint LEN=S->L->len;
        if(l<LEN)
            if(r<=LEN)S=S->L;
            else return find(S->L,l,LEN)+find(S->R,0,r-LEN);
        else l-=LEN,r-=LEN,S=S->R;
    }
    return S->v;
}
uint SA,SB,SC;
__always_inline uint rnd(){SA^=SA<<16;SA^=SA>>5;SA^=SA<<1;uint t=SA;SA=SB;SB=SC;SC^=t^SA;return SC;}
chr _s[1000005];
int main()
{ 
    uint n,q; 
    scanf("%u%u%u%u%u",&n,&q,&SA,&SB,&SC);
    if(!SA&&!SB&&!SC)
    {
        uint v=0;
        while(q)v^=q--;
        printf("%u\n",v);
        return 0;
    }
    for(uint i=0;i<n;i++)
    {
        uint si=rnd()%3;
        if(si==0)_s[i]='o';
        if(si==1)_s[i]='r';
        if(si==2)_s[i]='z';
    }
    S=new Seg(_s,_s+n);
    ullt ans=0;
    for(uint i=1;i<=q;++i)
    {
        if(!(rnd()&1))insert(S,rnd()%n),ans^=i;
        else
        {
            uint l=rnd()%n+1,r=rnd()%n+1;
            if(l>r)std::swap(l,r);
            ans^=find(S,l-1,r).ORZ+i;
        }
    }
    printf("%llu\n",ans);
    return 0;
}

/*
6 5
3488991686 1344677723 3466680979
*/