考场上看到这题以为splay于是跳过了= =,之后尝试自己写然而并是想不清楚关于3种tag的传递,WAWAWAWAWA,于是拿出qt的标程开始改自己的代码,然后二分查错。。。其实传递没那么复杂。。。染色tag时,把加法和等差数列的tag都清除,之后如果有加法或等差数列tag要打,那就和染色tag并存,向下穿tag时,先传染色tag,再传其他的,因为等差加和全加的tag,相当于覆盖在之前已经有的染色tag上的tag。
有一个技巧就是,因为线段树的遍历是按照前后顺序来的,于是等差数列的首项直接用全局变量delta来表示,打上一个tag之后直接delta加上这段的值,到达下一个位置的首项的值。
#include<cstdio>
#include<cstring>
#define maxl 50010
#define ls(x) x<<1
#define rs(x) x<<1|1
#define MOD 26
int n,m,head,key,x,y,z,a[maxl],delta,K,L,R,LL,RR;
int leaf[maxl];
char c;
struct node
{
int same,add,del,ins;//bian jia dengcha
}t[maxl<<2];
inline void build(int l,int r,int k)
{
if(l==r)
{
t[k].same=a[l];
leaf[l]=k;
return;
}
int mid=(l+r)>>1;
build(l,mid,ls(k));build(mid+1,r,rs(k));
t[k].same=-1;
}
inline void downtag(int l,int r,int k)
{
if(!t[k].add && !t[k].del && !t[k].ins && t[k].same==-1)
return;
int mid=(l+r)>>1;
if(t[k].same!=-1)
{
t[ls(k)].same=t[rs(k)].same=t[k].same;
t[ls(k)].add=t[ls(k)].del=t[ls(k)].ins=0;
t[rs(k)].add=t[rs(k)].del=t[rs(k)].ins=0;
}
if(t[k].add)
{
t[ls(k)].add+=t[k].add;t[ls(k)].add%=MOD;
t[rs(k)].add+=t[k].add;t[rs(k)].add%=MOD;
}
if(t[k].del !=0 || t[k].ins!=0)
{
t[ls(k)].del+=t[k].del;t[ls(k)].ins+=t[k].ins;
t[ls(k)].del%=MOD;t[ls(k)].ins%=MOD;
t[rs(k)].del+=t[k].del+(mid-l+1)*t[k].ins;t[rs(k)].ins+=t[k].ins;
t[rs(k)].del%=MOD;t[rs(k)].ins%=MOD;
}
t[k].add=t[k].del=t[k].ins=0;
t[k].same=-1;
}
inline void ask(int l,int r,int k)
{
if(LL<=l && r<=RR)
{
if(key==1)
{
t[k].same=K;t[k].add=t[k].del=t[k].ins=0;
return;
}
if(key==2)
{
t[k].add+=K;t[k].add%=MOD;
return;
}
if(key==4)
{
t[k].del+=delta;t[k].del%=MOD;
t[k].ins++;t[k].ins%=MOD;
delta+=r-l+1;delta%=MOD;
return;
}
}
int mid=(l+r)>>1;
downtag(l,r,k);
if(LL<=mid)
ask(l,mid,ls(k));
if(mid<RR)
ask(mid+1,r,rs(k));
}
inline void down(int l,int r,int k)
{
if(l==r)
{
a[l]=t[k].same;
a[l]+=t[k].add;a[l]%=MOD;
a[l]+=t[k].del;a[l]%=MOD;
return;
}
downtag(l,r,k);
int mid=(l+r)>>1;
down(l,mid,ls(k));
down(mid+1,r,rs(k));
}
int main()
{
scanf("%d%d",&n,&m);
getchar();
for(int i=1;i<=n;i++)
{
c=getchar();
a[i]=c-'A';
}
getchar();
build(1,n,1);
for(int i=1;i<=m;i++)
{
getchar();getchar();getchar();
scanf("%d",&key);
if(key==3)
{
scanf("%d\n",&K);
head+=K;
while(head>n)
head-=n;
continue;
}
scanf("%d%d",&L,&R);
if(key==1)
{
getchar();c=getchar();
K=c-'A';
}
else
if(key==2)
scanf("%d",&K);
getchar();
L=L+head;R=R+head;delta=1;
while(L>n)
L-=n;
while(R>n)
R-=n;
if(L<=R)
{
LL=L;RR=R;
ask(1,n,1);
}
else
{
LL=L;RR=n;ask(1,n,1);
LL=1;RR=R;ask(1,n,1);
}
}
down(1,n,1);
for(int i=1+head;i<=n;i++)
printf("%c",a[i]+'A');
for(int i=1;i<=head;i++)
printf("%c",a[i]+'A');
return 0;
}