线段树の模板
0x01 线段树
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int M=1e6;
char buf[1<<21],*p1=buf,*p2=buf;
ll n,m,q;
ll sum[M<<2],add[M<<2];
char sr[1<<21],z[20];
int C=-1,Z;
ll read(){
ll x=0,y=1;
char c=getchar();
while(c<'0'||c>'9'){
if(c=='-')
y=-1;
c=getchar();
}
while(c>='0'&&c<='9'){
x=x*10+c-'0';
c=getchar();
}
return x*y;
}
inline void Ot(){
fwrite(sr,1,C+1,stdout),C=-1;
}
inline void print(ll x){
if(C>1<<20)
Ot();
if(x<0)
sr[++C]=45,x=-x;
while(z[++Z]=x%10+48,x/=10);
while(sr[++C]=z[Z],--Z);
sr[++C]='\n';
}
inline void build(){
for(m=1;m<=n;m<<=1);
for(int i=m+1;i<=m+n;++i)
sum[i]=read();
for(int i=m-1;i;--i)
sum[i]=sum[i<<1]+sum[i<<1|1];
}
inline void update_part(int s,int t,ll v){
ll A=0,lc=0,rc=0,len=1;
for(s+=m-1,t+=m+1;s^t^1;s>>=1,t>>=1,len<<=1){
if(s&1^1)
add[s^1]+=v,lc+=len;
if(t&1)
add[t^1]+=v,rc+=len;
sum[s>>1]+=v*lc,sum[t>>1]+=v*rc;
}
for(lc+=rc,s>>=1;s;s>>=1)
sum[s]+=v*lc;
}
inline ll query_sum(int s,int t){
ll lc=0,rc=0,len=1,ans=0;
for(s+=m-1,t+=m+1;s^t^1;s>>=1,t>>=1,len<<=1){
if(s&1^1) ans+=sum[s^1]+len*add[s^1],lc+=len;
if(t&1) ans+=sum[t^1]+len*add[t^1],rc+=len;
if(add[s>>1]) ans+=add[s>>1]*lc;
if(add[t>>1]) ans+=add[t>>1]*rc;
}
for(lc+=rc,s>>=1;s;s>>=1)
if(add[s])
ans+=add[s]*lc;
return ans;
}
int main(){
n=read(),q=read(),build();
int opt,x,y;
ll k;
while(q--){
opt=read(),x=read(),y=read();
if(opt&1) k=read(),update_part(x,y,k);
else print(query_sum(x,y));
}
Ot();
return 0;
}
这也是\(P3372\)的std
0x02 普通平衡树
#include<bits/stdc++.h>
typedef long long ll;
typedef unsigned long long ull;
using namespace std;
const int MAXN=1E5+10;
struct node{
int son[2],fa,v,siz,tms;
}t[MAXN];
int Rt,cnt,n;
#define ls(x) t[x].son[0]
#define rs(x) t[x].son[1]
#define fa(x) t[x].fa
#define rson(x) (rs(fa(x))==x)
int nd(int val){
++cnt;
t[cnt].v=val;t[cnt].siz=t[cnt].tms=1;
return cnt;
}
void pushup(int x){
t[x].siz=t[ls(x)].siz+t[rs(x)].siz+t[x].tms;
}
void rotate(int x){
int y=fa(x),z=fa(y);
bool rsx=rson(x),rsy=rson(y);
if(z)
t[z].son[rsy]=x;
else Rt=x;
t[y].son[rsx]=t[x].son[!rsx];
t[x].son[!rsx]=y;
fa(t[y].son[rsx])=y;fa(y)=x;fa(x)=z;
pushup(y);
}
void splay(int x){
while(fa(x)){
if(fa(fa(x)))
rotate(rson(x)^rson(fa(x))?x:fa(x));
rotate(x);
}
pushup(x);
}
int find(int x,int val){
if(t[x].v==val)
return x;
if(t[x].v<val)
return rs(x)?find(rs(x),val):x;
else
return ls(x)?find(ls(x),val):x;
}
int Pred(int x){
splay(x);
x=ls(x);
while(rs(x))
x=rs(x);
return x;
}
int Succ(int x){
splay(x);
x=rs(x);
while(ls(x))
x=ls(x);
return x;
}
void insert(int val){
if(!Rt)
return Rt=nd(val),void();
int x=find(Rt,val);
if(t[x].v==val)
return splay(x),++t[x].tms,++t[x].siz,void();
int z=nd(val);
t[x].son[val>t[x].v]=z;
fa(z)=x;
while(x)
pushup(x),x=fa(x);
splay(z);
}
void erase(int val){
int x=find(Rt,val);
if(t[x].tms>1)
return splay(x),--t[x].tms,--t[x].siz,void();
splay(x);
if(rs(x)){
int y=Succ(x);
fa(rs(x))=0;
splay(y);Rt=y;
ls(Rt)=ls(x);
fa(ls(Rt))=Rt;
pushup(Rt);
}
else{
fa(ls(x))=0;
Rt=ls(x);
}
}
int Rank(int val){
int x=find(Rt,val);
if(t[x].v<val)
x=Succ(x);
splay(x);
return t[ls(x)].siz+1;
}
int kth(int x,int k){
if(t[ls(x)].siz+1<=k&&k<=t[ls(x)].siz+t[x].tms)
return t[x].v;
if(t[ls(x)].siz+t[x].tms>k)
return kth(ls(x),k);
else
return kth(rs(x),k-t[x].tms-t[ls(x)].siz);
}
int Pred_val(int val){
int x=find(Rt,val);
if(t[x].v<val)
return t[x].v;
return t[Pred(x)].v;
}
int Succ_val(int val){
int x=find(Rt,val);
if(t[x].v>val)
return t[x].v;
return t[Succ(x)].v;
}
signed main(){
scanf("%d",&n);
for(int i=1,opt,x;i<=n;i++){
scanf("%d%d",&opt,&x);
if(opt==1)
insert(x);
else
if(opt==2)
erase(x);
else
if(opt==3)
printf("%d\n",Rank(x));
else
if(opt==4)
printf("%d\n",kth(Rt,x));
else
if(opt==5)
printf("%d\n",Pred_val(x));
else
if(opt==6)
printf("%d\n",Succ_val(x));
}
}
这也是 \(P3369\) 的正解
0x03 文艺平衡树
#include<bits/stdc++.h>
#define Ls(x) tree[x].son[0]
#define Rs(x) tree[x].son[1]
#define rson(x) (tree[tree[x].fa].son[1]==x)
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
const int MAXN=100010;
struct node{
int son[2],val,siz,fa;
bool rev;
}tree[MAXN];
int root,cnt;
int n,q,L,R;
inline void pushup(const int &x){
tree[x].siz=tree[Ls(x)].siz+tree[Rs(x)].siz+1;
tree[Ls(x)].fa=x;tree[Rs(x)].fa=x;
}
inline void pushdown(const int &x){
if(tree[x].rev){
swap(Ls(x),Rs(x));
tree[Ls(x)].rev^=1;
tree[Rs(x)].rev^=1;
tree[x].rev=0;
}
}
void rotate(int x){
int fx=tree[x].fa,ffx=tree[fx].fa;
bool rsx=rson(x),rsfx=rson(fx);
if(ffx)
tree[ffx].son[rsfx]=x;
else
root=x;
tree[x].fa=ffx;tree[fx].fa=x;
tree[fx].son[rsx]=tree[x].son[rsx^1];
tree[x].son[rsx^1]=fx;
pushup(fx);
pushup(x);
}
stack<int> stk;
void splay(int x,int pos){
stk.push(x);
for(int i=x;tree[i].fa!=pos;i=tree[i].fa)
stk.push(tree[i].fa);
while(!stk.empty())
pushdown(stk.top()),stk.pop();
while(tree[x].fa!=pos){
int fx=tree[x].fa,ffx=tree[fx].fa;
if(ffx!=pos)
rotate(rson(x)^rson(fx)?x:fx);
rotate(x);
}
}
int find(int x,int pos){
pushdown(x);
if(pos==tree[Ls(x)].siz+1)
return x;
if(tree[Ls(x)].siz+1<pos)
return find(Rs(x),pos-tree[Ls(x)].siz-1);
else
return find(Ls(x),pos);
}
void rev(int l,int r){
int _l=find(root,l),_r=find(root,r+2);
splay(_l,0),splay(_r,_l);
tree[tree[_r].son[0]].rev^=1;
}
void print(int x){
pushdown(x);
if(Ls(x))
print(Ls(x));
if(x>=2&&x<n+2)
printf("%d ",x-1);
if(Rs(x))
print(Rs(x));
}
signed main(){
scanf("%d%d",&n,&q);
root=1;
for(int i=1;i<=n+2;i++){
tree[i].fa=i-1,tree[i].siz=n+3-i;
if(i!=n+2)
tree[i].son[1]=i+1;
}
tree[root].fa=0;
for(int i=1;i<=q;i++){
scanf("%d%d",&L,&R);
rev(L,R);
}
print(root);
puts("");
}
这也是 \(P3391\) 的正解
0x04 LCA
#include<algorithm>
#include<bitset>
#include<cctype>
#include<cerrno>
#include<clocale>
#include<cmath>
#include<complex>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<ctime>
#include<deque>
#include<exception>
#include<fstream>
#include<functional>
#include<limits>
#include<list>
#include<map>
#include<iomanip>
#include<ios>
#include<iosfwd>
#include<iostream>
#include<istream>
#include<ostream>
#include<queue>
#include<set>
#include<sstream>
#include<stack>
#include<stdexcept>
#include<streambuf>
#include<string>
#include<utility>
#include<vector>
#include<cwchar>
#include<cwctype>
using namespace std;
typedef long long ll;
const int N=501000;
int a,b,n,m,s,k=0;
int head[N],d[N],p[N][21];
struct node{
int v,next;
}e[N<<1];
inline ll read(){
ll x=0,y=1;
char c=getchar();
while (c<'0'||c>'9'){
if(c=='-')
y=-1;
c=getchar();
}
while(c>='0'&&c<='9'){
x=x*10+c-'0';
c=getchar();
}
return x*y;
}
void add(int n,int v){
e[k].v=v;
e[k].next=head[n];
head[n]=k++;
}
void dfs(int u,int fa){
d[u]=d[fa]+1;
p[u][0]=fa;
for(register int i=1;(1<<i)<=d[u];i++)
p[u][i]=p[p[u][i-1]][i-1];
for(register int i=head[u];i!=-1;i=e[i].next){
int v=e[i].v;
if(v!=fa)
dfs(v,u);
}
}
int lca(int a,int b){
if(d[a]>d[b])
swap(a,b);
for(register int i=20;i>=0;i--)
if(d[a]<=d[b]-(1<<i))
b=p[b][i];
if(a==b)
return a;
for(register int i=20;i>=0;i--){
if(p[a][i]==p[b][i])
continue;
else
a=p[a][i],b=p[b][i];
}
return p[a][0];
}
int main(){
memset(head,-1,sizeof(head));
n=read(),m=read(),s=read();
for(register int i=1;i<=n-1;i++){
register int x=read(),y=read();
add(x,y);
add(y,x);
}
dfs(s,0);
for(register int i=1;i<=m;i++){
a=read();
b=read();
printf("%d\n",lca(a,b));
}
return 0;
}
这也是 \(P3379\) 的正解