社区讨论
求大佬帮助!
P3373【模板】线段树 2参与者 2已保存回复 3
讨论操作
快速查看讨论及其快照的属性,并进行相关操作。
- 当前回复
- 3 条
- 当前快照
- 1 份
- 快照标识符
- @lo8fgrmp
- 此快照首次捕获于
- 2023/10/27 17:45 2 年前
- 此快照最后确认于
- 2023/10/27 17:45 2 年前
照着题解的线段树敲的,样例没过,看了半天没看出来,求调。
CPP#include<bits/stdc++.h>
using namespace std;
#define int long long
int n,m,a[100009],p;
struct lp{
int v,mul,add;
}s[400009];
void build(int k,int l,int r){
s[k].mul=1;
s[k].add=0;
if(l==r){
s[k].v=a[l]%p;
return;
}
int mid=l+r>>1;
build(2*k,l,mid);
build(2*k+1,mid+1,r);
s[k].v=(s[k*2].v+s[k*2+1].v)%p;
}
void pushdown(int k,int l,int r,int mid){
s[k*2].v=(s[k*2].v*s[k].mul+s[k].add*(m-l+1))%p;
s[k*2+1].v=(s[k*2+1].v*s[k].mul+s[k].add*(r-m))%p;
s[k*2].mul=(s[k*2].mul*s[k].mul)%p;
s[k*2+1].mul=(s[k*2+1].mul*s[k].mul)%p;
s[k*2].add=(s[k*2].add*s[k].mul+s[k].add)%p;
s[k*2+1].add=(s[k*2+1].add*s[k].mul+s[k].add)%p;
s[k].mul=1;
s[k].add=0;
}
void quick_mul(int k,int l,int r,int x,int y,int v){
if(x>r||y<l) return;
if(x<=l&&y>=r){
s[k].v=(s[k].v*v)%p;
s[k].mul=(s[k].mul*v)%p;
s[k].add=(s[k].add*v)%p;
return;
}
int mid=l+r>>1;
pushdown(k,l,r,mid);
quick_mul(k*2,l,mid,x,y,v);
quick_mul(k*2+1,mid+1,r,x,y,v);
s[k].v=(s[k*2].v+s[k*2+1].v)%p;
}
void quick_pls(int k,int l,int r,int x,int y,int v){
if(x>r||y<l) return;
if(x<=l&&y>=r){
s[k].add=(s[k].add+v)%p;
s[k].v=(s[k].v+v*(r-l+1))%p;
return;
}
int mid=l+r>>1;
pushdown(k,l,r,mid);
quick_pls(k*2,l,mid,x,y,v);
quick_pls(k*2+1,mid+1,r,x,y,v);
s[k].v=(s[k*2].v+s[k*2+1].v)%p;
}
int quick_qee(int k,int l,int r,int x,int y){
if(x>r||y<l) return 0;
if(l>=x&&r<=y) return s[k].v;
int mid=l+r>>1;
pushdown(k,l,r,mid);
return ((quick_qee(k*2,l,mid,x,y)+quick_qee(k*2+1,mid+1,r,x,y))%p);
}
signed main(){
scanf("%lld%lld%lld",&n,&m,&p);
for(int i=1;i<=n;i++){
scanf("%lld",&a[i]);
}
build(1,1,n);
for(int i=1;i<=m;i++){
int op;
scanf("%lld",&op);
if(op==1){
int t,g,c;
scanf("%lld%lld%lld",&t,&g,&c);
quick_mul(1,1,n,t,g,c);
int j=1;
/* while(s[j].v!=0){
cout<<s[j].v<<" ";
j++;
}
cout<<endl;*/
}
if(op==2){
int t,g,c;
scanf("%lld%lld%lld",&t,&g,&c);
quick_pls(1,1,n,t,g,c);
/* int j=1;
while(s[j].v!=0){
cout<<s[j].v<<" ";
j++;
}
cout<<endl;*/
}
if(op==3){
int t,g;
scanf("%lld%lld",&t,&g);
printf("%lld\n",quick_qee(1,1,n,t,g));
}
}
return 0;
}
回复
共 3 条回复,欢迎继续交流。
正在加载回复...