题意
对于一个序列,进行以下两种操作:
1、C L R 修改区间[L,R]上每个值为本身的平方,取mod 2018
2、Q L R 查询区间[L,R]的数值和
通过打表发现所有的数在前几项之后会进入循环部分,最大循环节为6,又所有未进入循环的部分<5所以我们对区间的维护是这样 的,定义sum[][]为这个节点的后6个数字,因为循环节是6所以我只要记录6个数字就可以,p[]为这个节点在循环节中的位置,cont[]为这个节点的操作次数,通过cont判断操作了几次如果>=5次说明这个节点进入循环部分不需要再更新到叶子节点了。
#include <iostream>
#include <algorithm>
using namespace std;
#define lson l,mid,rt<<1
#define rson mid+1,r,rt<<1|1
const int MAXN=50050;
int sum[MAXN<<2][6],lazy[MAXN<<2],pos[MAXN<<2],cont[MAXN<<2];
void pushup(int rt)
{
cont[rt]=min(cont[rt<<1],cont[rt<<1|1]);
pos[rt]=0;
if(cont[rt]>=5)
{
for(int i=0;i<6;i++)
sum[rt][i]=sum[rt<<1][(pos[rt<<1]+i)%6]+sum[rt<<1|1][(pos[rt<<1|1]+i)%6];
}
else sum[rt][0]=sum[rt<<1][pos[rt<<1]]+sum[rt<<1|1][pos[rt<<1|1]];
}
void build(int l,int r,int rt)
{
lazy[rt]=0,pos[rt]=0,cont[rt]=0;
if(l==r)
{
int k;
scanf("%d",&k);
sum[rt][0]=k;
return;
}
int mid=(l+r)>>1;
build(lson);
build(rson);
pushup(rt);
}
void pushdown(int rt)
{
if(lazy[rt])
{
lazy[rt<<1]+=lazy[rt];
lazy[rt<<1|1]+=lazy[rt];
pos[rt<<1]=(pos[rt<<1]+lazy[rt])%6;
pos[rt<<1|1]=(pos[rt<<1|1]+lazy[rt])%6;
lazy[rt]=0;
}
}
void update(int L,int R,int l,int r,int rt)
{
if(L<=l&&r<=R&&cont[rt]>=5)
{
lazy[rt]++;
pos[rt]=(pos[rt]+1)%6;
return;
}
if(l==r)
{
cont[rt]++;
if(cont[rt]<5)
sum[rt][0]=(sum[rt][0]*sum[rt][0])%2018;
else if(cont[rt]==5)
{
sum[rt][0]=(sum[rt][0]*sum[rt][0])%2018;
for(int i=1;i<6;i++)
sum[rt][i]=(sum[rt][i-1]*sum[rt][i-1])%2018;
}
else
pos[rt]=(pos[rt]+1)%6;
return;
}
pushdown(rt);
int mid=(l+r)>>1;
if(L<=mid) update(L,R,lson);
if(R>mid) update(L,R,rson);
pushup(rt);
}
int query(int L,int R,int l,int r,int rt)
{
if(L<=l&&r<=R)
{
return sum[rt][pos[rt]];
}
int mid=(l+r)>>1;
int ans=0;
pushdown(rt);
if(L<=mid) ans+=query(L,R,lson);
if(R>mid) ans+=query(L,R,rson);
return ans;
}
int main()
{
int t;
cin>>t;
int kace=1;
while(t--)
{
int n;
printf("Case #%d:\n",kace++);
scanf("%d",&n);
build(1,n,1);
int m;
scanf("%d",&m);
for(int i=0;i<m;i++)
{
char s[3];
int x,y;
scanf("%s%d%d",s,&x,&y);
if(s[0]=='Q')
{
int ans=query(x,y,1,n,1);
printf("%d\n",ans);
}
else if(s[0]=='C')
{
update(x,y,1,n,1);
}
}
}
}