题意:中文题
思路:将每个点展开为 x*lazy1+lazy2, lazy1标记乘了多少 lazy2标记加了多少,每次区间乘的时候即 sum*c=(x*lazy1+lazy2)*c=x*lazy1*c+lazy2*c,区间加的时候为sum+c=(x*lazy1+lazy2)+c=x*lazy1+lazy2+c,每次对lazy标记的时候乘要同时对lazy1和lazy2进行标记
AC代码:
#include "iostream" #include "string.h" #include "stack" #include "queue" #include "string" #include "vector" #include "set" #include "map" #include "algorithm" #include "stdio.h" #include "math.h" #define ll long long #define bug(x) cout<<x<<" "<<"UUUUU"<<endl; #define mem(a) memset(a,0,sizeof(a)) #define mp(x,y) make_pair(x,y) #define pb(x) push_back(x) #define lrt (root*2) #define rrt (root*2+1) #define len (r-l+1) #pragma comment(linker, "/STACK:102400000,102400000") using namespace std; const long long INF = 1e18+1LL; const int inf = 1e9+1e8; const int N=1e5+100; const ll mod=1e9+7; ll a[N<<2],lazy1[N<<2],lazy2[N<<2],n,m,p; void push_up(int root){ a[root]=(a[lrt]+a[rrt])%p; } void push_down(int root, int m){ lazy1[lrt]=(lazy1[root]*lazy1[lrt])%p; lazy1[rrt]=(lazy1[root]*lazy1[rrt])%p; lazy2[lrt]=((lazy2[lrt]*lazy1[root])%p+lazy2[root])%p; lazy2[rrt]=((lazy2[rrt]*lazy1[root])%p+lazy2[root])%p; a[lrt]=((a[lrt]*lazy1[root])%p+(lazy2[root]*(m-(m>>1))%p))%p; a[rrt]=((a[rrt]*lazy1[root])%p+(lazy2[root]*(m>>1))%p)%p; lazy1[root]=1,lazy2[root]=0; } void creat(int root, int l, int r){ if(l==r){ scanf("%lld",&a[root]); a[root]%=p; return; } int mid=l+r>>1; creat(lrt, l, mid); creat(rrt, mid+1, r); push_up(root); } void updata1(int root, int l, int r, int L, int R, int c){ if(l==L && r==R){ lazy1[root]=(lazy1[root]*(c%p))%p; lazy2[root]=(lazy2[root]*(c%p))%p; a[root]=(a[root]*(c%p))%p; return; } if(lazy1[root]!=1 || lazy2[root]>0) push_down(root,len); int mid=l+r>>1; if(R<=mid)updata1(lrt, l, mid, L, R, c); else if(L>mid) updata1(rrt, mid+1, r, L, R, c); else updata1(lrt, l, mid, L, mid, c) , updata1(rrt, mid+1, r, mid+1, R, c); push_up(root); } void updata2(int root, int l, int r, int L, int R, int c){ if(l==L && r==R){ lazy2[root]=(((lazy2[root]+(c%p))%p))%p; a[root]=((a[root]+(c%p)*len)%p)%p; return; } if(lazy1[root]!=1 || lazy2[root]>0) push_down(root,len); int mid=l+r>>1; if(R<=mid) updata2(lrt, l, mid, L, R, c); else if(L>mid) updata2(rrt, mid+1, r, L, R, c); else updata2(lrt, l, mid, L, mid, c) , updata2(rrt, mid+1, r, mid+1, R, c); push_up(root); } ll query(int root, int l, int r, int L, int R){ if(l==L && r==R){ return a[root]%p; } if(lazy1[root]!=1 || lazy2[root]>0) push_down(root,len); int mid=l+r>>1; if(R<=mid) return query(lrt, l, mid, L, R)%p; else if(L>mid) return query(rrt, mid+1, r, L, R)%p; else return (query(lrt, l, mid, L, mid)+query(rrt, mid+1, r, mid+1, R))%p; } int main(){ ///ios::sync_with_stdio(false),cin.tie(0),cout.tie(0); cin>>n>>p; for(int i=0; i<=4*n; ++i) lazy1[i]=1; creat(1,1,n); cin>>m; int t,c,l,r; for(int i=1; i<=m; ++i){ scanf("%d%d%d",&t,&l,&r); if(t==1){ scanf("%d",&c); updata1(1,1,n,l,r,c); } else if(t==2){ scanf("%d",&c); updata2(1,1,n,l,r,c); } if(t==3) printf("%lld ",(query(1,1,n,l,r)+p)%p); } return 0; }