rt,评测记录
代码:
#include<bits/stdc++.h>
using namespace std;
#define MAXN 100005
#define SIZE 400005
typedef long long ll;
#define int ll
struct node
{
int l,r;
ll val,tag,tag2;
node(int al=0,int ar=0,ll av=0,ll at=0,ll at2=1)
{
l=al,r=ar,val=av,tag=at,tag2=at2;
}
}seg[SIZE]; // segment tree 线段树
int n,T,m;
ll a[MAXN];
bool son[SIZE];
ll build(int p,int x,int y) //建树
{
if(x==y)
{
seg[p]=node(x,y,a[x],0,1);
son[p]=0;
//cout<<"build("<<p<<","<<x<<","<<y<<")="<<a[x]<<"\n";
return a[x]%m;
}
int mid=x+((y-x)>>1);
ll ret = ( build(p*2,x,mid) + build(p*2+1,mid+1,y) )%m;
seg[p]=node(x,y,ret,0,1);
son[p]=1;
//cout<<"build("<<p<<","<<x<<","<<y<<")="<<ret<<"\n";
return ret;
}
void pushdown(int p) //下传懒标签
{
if(son[p])
{
//啊啊啊啊啊啊啊啊啊啊啊啊
//每日发疯 (1/1)
seg[p*2].tag2*=seg[p].tag2;
seg[p*2].tag2%=m;
seg[p*2].tag*=seg[p].tag2;
seg[p*2].tag%=m;
seg[p*2].tag+=seg[p].tag;
seg[p*2].tag%=m;
seg[p*2+1].tag2*=seg[p].tag2;
seg[p*2+1].tag2%=m;
seg[p*2+1].tag*=seg[p].tag2;
seg[p*2+1].tag%=m;
seg[p*2+1].tag+=seg[p].tag;
seg[p*2+1].tag%=m;
}
seg[p].val*=seg[p].tag2;
seg[p].val%=m;
seg[p].tag2=1;
seg[p].val+=(seg[p].r-seg[p].l+1)*seg[p].tag;
seg[p].val%=m;
seg[p].tag=0;
}
ll sum(int p,int x,int y) //区间求和
{
if(seg[p].tag || seg[p].tag2)
{
pushdown(p);
}
int sl=seg[p].l, sr=seg[p].r;
if(sl==x && sr==y)
{
//cout<<"sum("<<p<<","<<x<<","<<y<<")="<<seg[p].val<<"\n";
return seg[p].val%m;
}
int mid=sl+((sr-sl)>>1);
ll p1=0,p2=0;
if(son[p])
{
if(x<=mid)
{
p1=sum(p*2,x,min(mid,y))%m;
}
if(y>mid)
{
p2=sum(p*2+1,max(mid+1,x),y)%m;
}
}
//cout<<"sum("<<p<<","<<x<<","<<y<<")="<<p1+p2<<"\n";
return (p1+p2)%m;
}
void add(int p,int x,int y,int d) //区间加
{
//cout<<"add("<<p<<","<<x<<","<<y<<","<<d<<")\n";
int sl=seg[p].l, sr=seg[p].r;
pushdown(p);
if(sl>=x && sr<=y)
{
seg[p].tag+=d;
seg[p].tag%=m;
//cout<<"add: seg[p]: tag="<<seg[p].tag<<"\n";
return;
}
seg[p].val+=(min(y,sr)-max(x,sl)+1)*d;
seg[p].val%=m;
//cout<<"add: seg[p]: val="<<seg[p].val<<"\n";
int mid = (sl + sr) >> 1;
if(son[p])
{
if(mid>=x)
{
add(p*2,x,y,d);
}
if(mid<y)
{
add(p*2+1,x,y,d);
}
}
}
void mul(int p,int x,int y,int d) //区间乘
{
//cout<<"mul("<<p<<","<<x<<","<<y<<","<<d<<")\n";
int sl=seg[p].l, sr=seg[p].r;
pushdown(p);
if(sl>=x && sr<=y)
{
seg[p].tag2*=d;
seg[p].tag2%=m;
seg[p].tag*=d;
seg[p].tag%=m;
//cout<<"mul: seg[p]: val="<<seg[p].val<<" tag=0 tag2="<<seg[p].tag2<<"\n";
return;
}
//cout<<"mul: seg[p]: l="<<sl<<" r="<<sr<<"\n";
//cout<<"mul: seg[p].val更新前: sum(1,max(x,sl),min(y,sr))="<<sum(1,max(x,sl),min(y,sr))<<"\n";
//cout<<"mul: seg[p]: val="<<seg[p].val<<"\n";
int mid = (sl + sr) >> 1;
ll p1=0,p2=0;
if(son[p])
{
if(mid>=x)
{
mul(p*2,x,y,d);
}
if(mid<y)
{
mul(p*2+1,x,y,d);
}
p1 = seg[p*2].val * seg[p*2].tag2 + seg[p*2].tag;
p2 = seg[p*2+1].val * seg[p*2+1].tag2 + seg[p*2+1].tag;
}
//cout<<"mul("<<p<<","<<x<<","<<y<<","<<d<<")\n";
//cout<<"p1="<<p1<<" p2="<<p2<<"\n";
seg[p].val=(p1+p2)%m;
}
signed main()
{
scanf("%lld%lld%lld",&n,&T,&m);
for(int i=1;i<=n;i++)
{
scanf("%lld",&a[i]);
}
build(1,1,n);
while(T--)
{
int op,x,y,k;
scanf("%lld%lld%lld",&op,&x,&y);
if(op==1)
{
scanf("%lld",&k);
mul(1,x,y,k);
}
else if(op==2)
{
scanf("%lld",&k);
add(1,x,y,k);
}
else
{
printf("%lld\n",sum(1,x,y));
}
/*
for(int i=1;seg[i].l;i++)
{
printf("[%lld,%lld] sum=%lld tag=%lld tag2=%lld\n", seg[i].l, seg[i].r, seg[i].val, seg[i].tag, seg[i].tag2);
}
//*/
}
return 0;
}