HDU 4348 主席树(新的线段树区间查询方法)
今天涨姿势了,发现线段树可以不putdown就可以完成求和的区间查询,果然本渣渣太弱了。
//#include <bits\stdc++.h>
//#pragma comment(linker,"/STACK:102400000,102400000")
#include <cstdio>
#include <cstring>
#include <iostream>
#include <cstdlib>
#include <vector>
#include <stack>
#include <queue>
#include <map>
#include <set>
#include <ctime>
#include <cmath>
#include <algorithm>
#include <bitset>
#define sqr(x) ((x)*(x))
#define lson (p<<1)
#define rson (lson | 1)
#define EPS 1e-10
#define PII pair<int,int>
#define PLI pair<LL,int>
#define PLL pair<LL,LL>
#define PIL pair<int,LL>
#define mk(x,y) make_pair(x,y)
#define lowbit(x) (x&(-x))
#define FRfreopen("in.txt","r",stdin)
#define FWfreopen("out.txt","w",stdout)
using namespace std;
template <class T>
inline void read(T &x){char c =getchar(); x = 0;while(!isdigit(c))c = getchar();while(isdigit(c)){x=x*10 +c-'0';c = getchar();}}
template <class T>
inline void rd(T &res) {static char ch;bool sgn = false;while (ch = getchar(), ch < '0' || ch > '9') if (ch =='-') sgn = true;
res = ch - 48;while (ch = getchar(), ch >= '0' && ch <='9') res = res * 10 + ch - 48; res = sgn ? -res : res;}
template <class T> void Out(T a) {if(a < 0){putchar('-');a = -a;}if(a >= 10)Out(a / 10);putchar(a % 10 +'0'); }
typedef long long LL;
const int N = 1e5+10;
struct Node
{
intl,r;
LLadd,sum;
}tree[N*30];
int n,m,cnt,head[N];
int build(int l,int r)
{
intp = ++cnt;
tree[p].add= 0;
if(l== r)
{
rd(tree[p].sum);
tree[p].l= tree[p].r = 0;
returnp;
}
intm = r + l >> 1;
tree[p].l= build(l,m);
tree[p].r= build(m+1,r);
tree[p].sum= tree[tree[p].l].sum + tree[tree[p].r].sum;
returnp;
}
int update(int root,int l,int r,int s,intt,int val)
{
intp = ++cnt;
tree[p].sum= tree[root].sum;
tree[p].add= tree[root].add;
tree[p].l= tree[root].l;
tree[p].r= tree[root].r;
if(s<=l&& r<=t)
{
tree[p].sum+= (r-l+1LL) * val;
tree[p].add+= val;
returnp;
}
intm = r + l >> 1;
if(s<=m)tree[p].l = update(tree[root].l,l,m,s,t,val);
if(t>m)tree[p].r = update(tree[root].r,m+1,r,s,t,val);
tree[p].sum= tree[tree[p].l].sum + tree[tree[p].r].sum + tree[p].add*(r-l+1LL); //wa 了无数次在这个地方
returnp;
}
LL query(int p,int l,int r,int s,int t)
{
if(s<=l&& r<=t) return tree[p].sum;
intm = l + r >> 1;
LLans = tree[p].add * ( min(r,t) - max(l,s) + 1LL);
if(s<=m)ans += query(tree[p].l,l,m,s,t);
if(t>m)ans += query(tree[p].r,m+1,r,s,t);
returnans;
}
char c[10];
int main()
{
while(~scanf("%d%d",&n,&m))
{
intnow = 0,l,r,w;
cnt= 0;
head[0]= build(1,n);
while(m--)
{
scanf("%s",c);
if(c[0]== 'Q')
{
rd(l),rd(r);
Out(query(head[now],1,n,l,r)),puts("");
}elseif(c[0] == 'C')
{
rd(l),rd(r),rd(w);
head[now+1]= update(head[now],1,n,l,r,w);
now++;
}elseif(c[0] == 'H')
{
rd(l),rd(r),rd(w);
Out(query(head[w],1,n,l,r)),puts("");
}elserd(now);
}
}
return 0;
}