http://acm.hdu.edu.cn/showproblem.php?pid=4348
题意:如题hhh
C l r v :区间 l ~ r 所有数加上v
H l r t : 查询时间 t 时 区间 l~r 的区间和
Q l r : 查询当前时间的区间和
B t : 将当前时间置为 t
主席树的板子,码着
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<stdio.h>
#include<string.h>
#include<queue>
#include<cmath>
#include<map>
#include<set>
#include<vector>
using namespace std;
#define inf 0x3f3f3f3f
#define lson l,mid,rt<<1
#define rson mid+1,r,rt<<1|1
#define mem(a,b) memset(a,b,sizeof(a));
#define lowbit(x) x&-x;
typedef long long ll;
typedef unsigned long long ull;
const double eps = 1e-6;
const int maxn = 1e5+5;
const int mod = 1e9+7;
inline int read()
{
int x=0,f=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
return x*f;
}
int n,m,tot,rt[maxn*40],sz;
struct node{
int l,r;
ll sum,add;
}T[maxn*40];
ll num[maxn];
void pushup(int rt){
T[rt].sum = T[T[rt].l].sum + T[T[rt].r].sum;
}
void pushdown(int rt,int len){
if(T[rt].add){
T[T[rt].l].add += T[rt].add;
T[T[rt].r].add += T[rt].add;
T[T[rt].l].sum += 1ll*T[rt].add*(len-len>>1);
T[T[rt].r].sum += 1ll*T[rt].add*(len>>1);
T[rt].add = 0;
}
}
void build(int l,int r,int &rt){
rt = ++tot;
T[rt].l = T[rt].r = T[rt].add = 0;
if(l == r){
T[rt].sum = num[l];
return;
}
int mid = (l+r)>>1;
build(l,mid,T[rt].l);
build(mid+1,r,T[rt].r);
T[rt].sum = T[T[rt].l].sum + T[T[rt].r].sum;
}
void update(int &rt,int las,int L,int R,int l,int r,ll v){
T[rt = ++tot] = T[las];
if(L <= l && r <= R){
T[rt].add += v;
T[rt].sum += 1ll*(r-l+1)*v;
return ;
}
//pushdown(rt,r-l+1);
int mid = (l+r)>>1;
if(L <= mid) update(T[rt].l,T[las].l,L,R,l,mid,v);
if(R > mid) update(T[rt].r,T[las].r,L,R,mid+1,r,v);
T[rt].sum = T[T[rt].l].sum + T[T[rt].r].sum + 1ll*(r-l+1)*T[rt].add;
}
ll query(int rt,int L,int R,int l,int r,ll pre){
if(L <= l && r <= R){
return T[rt].sum+1ll*pre*(r-l+1);
}
//pushdown(rt,r-l+1);
ll res = 0;
int mid = (l+r)>>1;
if(L <= mid) res += query(T[rt].l,L,R,l,mid,pre+T[rt].add);
if(R > mid) res += query(T[rt].r,L,R,mid+1,r,pre+T[rt].add);
return res;
}
int main() {
int ca = 1;
while(~scanf("%d%d",&n,&m)){
for(int i = 1; i <= n; i++)
scanf("%lld",&num[i]);
tot = 0,sz = 0;
build(1,n,rt[0]);
char op[2];
int l,r,t;
ll v;
while(m--){
scanf("%s",op);
if(op[0] == 'C'){
scanf("%d%d%lld",&l,&r,&v);
update(rt[sz+1],rt[sz],l,r,1,n,v);
sz++;
}
else if(op[0] == 'H'){
scanf("%d%d%d",&l,&r,&t);
printf("%lld\n",query(rt[t],l,r,1,n,0));
}else if(op[0] == 'B'){
scanf("%d",&sz);
}else{
scanf("%d%d",&l,&r);
printf("%lld\n",query(rt[sz],l,r,1,n,0));
}
}
}
}
本文介绍了一种基于主席树的数据结构实现,用于处理区间加法更新和区间和查询问题。通过实例讲解了如何构建、更新和查询主席树,适用于算法竞赛和高级数据结构学习。
1819

被折叠的 条评论
为什么被折叠?



