目录:
###洛谷 P2068 统计和
很裸的一道模板题,直接上代码了。
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<cstring>
#define ll long long
#define ls (rt<<1)
#define rs (rt<<1|1)
#define mid ((tree[rt].r+tree[rt].l)>>1)
#define fp(i,a,b) for(register int i=a;i<=b;++i)
using namespace std;
struct arr{
ll l,r,sum,tag,tag1;
}tree[500000];
int n,m;
inline ll read(){
int x=0,w=1;char ch=0;
while(ch!='0'&&(ch<'0'||ch>'9')) ch=getchar();
if(ch=='-') w=-1,ch=getchar();
while(ch>='0'&&ch<='9') x=(x<<3)+(x<<1)+(ch-48),ch=getchar();
return x*w;
}
inline void pushup(int rt){tree[rt].sum=(tree[ls].sum+tree[rs].sum);}
inline void pushdown(int rt){
if(tree[rt].tag){
tree[ls].tag+=tree[rt].tag;
tree[rs].tag+=tree[rt].tag;
tree[ls].sum=tree[ls].sum+((tree[ls].r-tree[ls].l+1)*tree[rt].tag);
tree[rs].sum=tree[rs].sum+((tree[rs].r-tree[rs].l+1)*tree[rt].tag);
tree[rt].tag=0;
}
}
void build(int l,int r,int rt) {
tree[rt].l=l;tree[rt].r=r;tree[rt].tag1=1;
if(l==r) return ;
int midd=(l+r)>>1;
build(l,midd,ls);build(midd+1,r,rs);
pushup(rt);
}
void updata(int l,int r,ll c,int rt) {
if(l==tree[rt].l&&tree[rt].r==r) {
tree[rt].sum=(tree[rt].sum+(tree[rt].r-tree[rt].l+1)*c);
tree[rt].tag+=c;
return ;
}
pushdown(rt);
if(r<=mid) updata(l,r,c,ls);
else if(l>mid) updata(l,r,c,rs);
else {updata(l,mid,c,ls);updata(mid+1,r,c,rs); }
pushup(rt);
}
ll query(int l,int r,int rt) {
if(l==tree[rt].l&&tree[rt].r==r) return tree[rt].sum;
pushdown(rt);
ll ans=0;
if(r<=mid) ans+=query(l,r,ls);
else if(l>mid) ans+=query(l,r,rs);
else {ans+=query(l,mid,ls);ans+=query(mid+1,r,rs); }
pushup(rt);
return ans;
}
int main(){
n=read();m=read();
build(1,n,1);
fp(i,1,m) {
char op;cin>>op;
if(op=='x'){int l=read(),k=read();updata(l,l,k,1);}
if(op=='y'){int l=read(),r=read();printf("%lld\n",query(l,r,1));}
}
}
###洛谷 P3373 线段树2
这里有几个注意点:
1.我们要下传两个tag,一个用于乘法,另一个用于加法
2.我们在下传乘法的tag时,同时要更新加法的tag。
3.我们在下传tag的时候,必须得先更新乘法的,在更新加法的。
4.具体看代码吧(自我感觉代码可读性还可以的吧)
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<cstring>
#define ll long long
#define ls (rt<<1)
#define rs (rt<<1|1)
#define mid ((tree[rt].r+tree[rt].l)>>1)
#define fp(i,a,b) for(register int i=a;i<=b;++i)
using namespace std;
struct arr{
ll l,r,sum,tag,tag1;
}tree[500000];
int n,m,p;
inline ll read(){
int x=0,w=1;char ch=0;
while(ch!='0'&&(ch<'0'||ch>'9')) ch=getchar();
if(ch=='-') w=-1,ch=getchar();
while(ch>='0'&&ch<='9') x=(x<<3)+(x<<1)+(ch-48),ch=getchar();
return x*w;
}
inline void pushup(int rt){tree[rt].sum=(tree[ls].sum+tree[rs].sum)%p;}
inline void pushdown(int rt){
if(tree[rt].tag1!=1){
tree[ls].tag1*=tree[rt].tag1;tree[ls].tag1%=p;
tree[rs].tag1*=tree[rt].tag1;tree[rs].tag1%=p;
tree[ls].tag*=tree[rt].tag1;tree[ls].tag%=p;
tree[rs].tag*=tree[rt].tag1;tree[rs].tag%=p;
tree[ls].sum=tree[ls].sum*tree[rt].tag1;tree[ls].sum%=p;
tree[rs].sum=tree[rs].sum*tree[rt].tag1;tree[rs].sum%=p;
tree[rt].tag1=1;
}
if(tree[rt].tag){
tree[ls].tag+=tree[rt].tag;tree[ls].tag%=p;
tree[rs].tag+=tree[rt].tag;tree[rs].tag%=p;
tree[ls].sum=tree[ls].sum+((tree[ls].r-tree[ls].l+1)*tree[rt].tag%p);
tree[rs].sum=tree[rs].sum+((tree[rs].r-tree[rs].l+1)*tree[rt].tag%p);
tree[rt].tag=0;
}
}
void build(int l,int r,int rt) {
tree[rt].l=l;tree[rt].r=r;tree[rt].tag1=1;
if(l==r) return ;
int midd=(l+r)>>1;
build(l,midd,ls);build(midd+1,r,rs);
pushup(rt);
}
void updata(int l,int r,ll c,int rt) {
if(l==tree[rt].l&&tree[rt].r==r) {
tree[rt].sum=(tree[rt].sum+(tree[rt].r-tree[rt].l+1)*c%p);
tree[rt].tag+=c;tree[rt].tag%=p;
return ;
}
pushdown(rt);
if(r<=mid) updata(l,r,c,ls);
else if(l>mid) updata(l,r,c,rs);
else {updata(l,mid,c,ls);updata(mid+1,r,c,rs); }
pushup(rt);
}
void updata1(int l,int r,ll c,int rt) {
if(l==tree[rt].l&&tree[rt].r==r) {
tree[rt].sum=(tree[rt].sum*c)%p;
tree[rt].tag1*=c;tree[rt].tag1%=p;
tree[rt].tag*=c;tree[rt].tag%=p;
return ;
}
pushdown(rt);
if(r<=mid) updata1(l,r,c,ls);
else if(l>mid) updata1(l,r,c,rs);
else {updata1(l,mid,c,ls);updata1(mid+1,r,c,rs); }
pushup(rt);
}
ll query(int l,int r,int rt) {
if(l<=tree[rt].l&&tree[rt].r<=r) return tree[rt].sum;
pushdown(rt);
ll ans=0;
if(l<=mid) ans+=query(l,r,ls),ans%=p;
if(r>mid) ans+=query(l,r,rs),ans%=p;
pushup(rt);
return ans;
}
int main(){
n=read();m=read();p=read();
build(1,n,1);
fp(i,1,n) { int x=read();updata(i,i,x,1);}
fp(i,1,m) {
int op=read();
if(op==1){ int l=read(),r=read(),k=read(); updata1(l,r,k,1);}
if(op==2){ int l=read(),r=read(),k=read(); updata(l,r,k,1);}
if(op==3){ int l=read(),r=read(); printf("%lld\n",query(l,r,1));}
}
}