线段树水题集合
用的都是《算法竞赛》的码风哦
极简 ,开和关用 1 0 表示 ,然后区间修改,区间求和,裸题
这两道题一模一样
#include <bits/stdc++.h>
using namespace std;
const int N=100005;
#define ll long long
ll ls(ll p){return p<<1;}
ll rs(ll p){return p<<1|1;}
ll n,m,sum[N<<2];
bool tag[N<<2];
void addtag(ll p,ll pl,ll pr){
sum[p]=pr-pl+1-sum[p];
tag[p]=!tag[p];
}
void pushdown(ll p,ll pl,ll pr){
if(tag[p]){
ll mid=(pl+pr)>>1;
addtag(ls(p),pl,mid);
addtag(rs(p),mid+1,pr);
tag[p]=!tag[p];
}
}
void pushup(ll p){
sum[p]=sum[ls(p)]+sum[rs(p)];
}
void update(ll p,ll L,ll R,ll pl,ll pr){
if(L<=pl&&R>=pr){
addtag(p,pl,pr);
return;
}
pushdown(p,pl,pr);
ll mid=(pl+pr)>>1;
if(L<=mid)update(ls(p),L,R,pl,mid);
if(R>mid)update(rs(p),L,R,mid+1,pr);
pushup(p);
}
ll query(ll p,ll L,ll R,ll pl,ll pr){
if(L<=pl&&R>=pr){
return sum[p];
}
pushdown(p,pl,pr);
ll res=0;
ll mid=(pl+pr)>>1;
if(L<=mid)res+=query(ls(p),L,R,pl,mid);
if(R>mid)res+=query(rs(p),L,R,mid+1,pr);
return res;
}
int main(){
cin>>n>>m;
for(int i=1;i<=m;i++){
int c,a,b;
cin>>c>>a>>b;
if(c){
cout<<query(1,a,b,1,n)<<endl;
}else{
update(1,a,b,1,n);
}
}
return 0;
}
sum[]表示这个区间中最长的满足要求的连续子串的长度 suml[]表示这个区间中前缀满足要求的连续子串的长度
sumr[]表示这个区间中后缀满足要求的连续子串的长度
#include <bits/stdc++.h>
using namespace std;
#define ll long long
ll ls(ll p){return p<<1;}
ll rs(ll p){return p<<1|1;}
const int N=200005;
bool a[N];
ll n,q;
ll sum[N<<2],suml[N<<2],sumr[N<<2];
void build(ll p,ll pl,ll pr){
sum[p]=suml[p]=sumr[p]=1;
if(pl==pr)return;
ll mid=(pl+pr)>>1;
build(ls(p),pl,mid);
build(rs(p),mid+1,pr);
}
void pushup(ll p,ll pl,ll pr){
ll mid=(pl+pr)>>1;
ll L=mid-pl+1,R=pr-mid;
sum[p]=max(sum[ls(p)],sum[rs(p)]);
suml[p]=suml[ls(p)],sumr[p]=sumr[rs(p)];
if(a[mid]!=a[mid+1]){
sum[p]=max(sum[p],sumr[ls(p)]+suml[rs(p)]);
if(suml[ls(p)]==L)suml[p]=L+suml[rs(p)];
if(sumr[rs(p)]==R)sumr[p]=R+sumr[ls(p)];
}
}
void update(ll p,ll x,ll pl,ll pr){
if(pl==pr&&pl==x){
a[pl]=!a[pl];
return;
}
ll mid=(pl+pr)>>1;
if(x<=mid)update(ls(p),x,pl,mid);
else update(rs(p),x,mid+1,pr);
pushup(p,pl,pr);
}
int main(){
cin>>n>>q;
build(1,1,n);
for(int i=1;i<=q;i++){
ll x;
cin>>x;
update(1,x,1,n);
cout<<sum[1]<<endl;
}
return 0;
}
洛谷P2357
板子
#include <bits/stdc++.h>
using namespace std;
#define ll long long
const int N=200005;
ll ls(ll p){return p<<1;}
ll rs(ll p){return p<<1|1;}
ll n,f,a[N],tree[N<<2],tag[N<<2];
void pushup(ll p){
tree[p]=tree[ls(p)]+tree[rs(p)];
}
void build(ll p,ll pl,ll pr){
if(pl==pr){
tree[p]=a[pl];
return;
}
ll mid=(pl+pr)>>1;
build(ls(p),pl,mid);
build(rs(p),mid+1,pr);
pushup(p);
}
void addtag(ll p,ll pl,ll pr,ll x){
tag[p]+=x;
tree[p]+=x*(pr-pl+1);
}
void pushdown(ll p,ll pl,ll pr){
if(tag[p]){
ll mid=(pl+pr)>>1;
addtag(ls(p),pl,mid,tag[p]);
addtag(rs(p),mid+1,pr,tag[p]);
tag[p]=0;
}
}
void update(ll p,ll L,ll R,ll pl,ll pr,ll x){
if(L<=pl&&R>=pr){
addtag(p,pl,pr,x);
return;
}
pushdown(p,pl,pr);
ll mid=(pl+pr)>>1;
if(L<=mid)update(ls(p),L,R,pl,mid,x);
if(R>mid)update(rs(p),L,R,mid+1,pr,x);
pushup(p);
}
ll query(ll p,ll L,ll R,ll pl,ll pr){
if(L<=pl&&R>=pr){
return tree[p];
}
pushdown(p,pl,pr);
ll res=0;
ll mid=(pl+pr)>>1;
if(L<=mid)res+=query(ls(p),L,R,pl,mid);
if(R>mid)res+=query(rs(p),L,R,mid+1,pr);
return res;
}
int main(){
cin>>n>>f;
for(int i=1;i<=n;i++){
cin>>a[i];
}
build(1,1,n);
for(int i=1;i<=f;i++){
ll o,l,r,k;
cin>>o;
if(o==1){
cin>>l>>r>>k;
update(1,l,r,1,n,k);
}
if(o==2){
cin>>k;
update(1,1,1,1,n,k);
}
if(o==3){
cin>>k;
update(1,1,1,1,n,-k);
}
if(o==4){
cin>>l>>r;
cout<<query(1,l,r,1,n)<<endl;
}
if(o==5){
cout<<query(1,1,1,1,n)<<endl;
}
}
return 0;
}
更新ing