HDU 4348 主席树(新的线段树区间查询方法)

11 篇文章 0 订阅
4 篇文章 0 订阅

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;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值