ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

[HDU4348]To the moon(主席树+标记永久化)

2019-02-23 09:41:08  阅读:284  来源: 互联网

标签:int scanf d% mid moon 永久化 sm HDU4348 rson


学可持久化treap的时候才发现自己竟然没写过需要标记下传的主席树,然而现在发现大部分操作都可以标记永久化,下传会增大占用空间。

这题一种写法是和普通的线段树一样标记下传,注意所有修改操作(包括put())都要新建点。于是MLE了。

 1 #include<cstdio>
 2 #include<algorithm>
 3 #define lson v[x].ls,L,mid
 4 #define rson v[x].rs,mid+1,R
 5 #define rep(i,l,r) for (int i=(l); i<=(r); i++)
 6 typedef long long ll;
 7 using namespace std;
 8 
 9 const int N=100010;
10 char op;
11 int n,m,l,r,k,tim,nd,a[N],rt[N];
12 struct Tr{ int ls,rs; ll sm,tag; }v[N*25];
13 
14 void put(int &x,int L,int R,ll k){ if (x) v[++nd]=v[x],x=nd,v[nd].sm+=(R-L+1)*k,v[nd].tag+=k; }
15 
16 void push(int x,int L,int R){ int mid=(L+R)>>1; if (v[x].tag) put(lson,v[x].tag),put(rson,v[x].tag),v[x].tag=0; }
17 
18 void build(int &x,int L,int R){
19     x=++nd;
20     if (L==R){ v[x]=(Tr){0,0,a[L],0}; return; }
21     int mid=(L+R)>>1;
22     build(lson); build(rson);
23     v[x].sm=v[v[x].ls].sm+v[v[x].rs].sm; v[x].tag=0;
24 }
25 
26 void ins(int y,int &x,int L,int R,int l,int r,int k){
27     x=++nd; v[x]=v[y];
28     if (L==l && r==R){ v[x].sm+=1ll*(R-L+1)*k; v[x].tag+=k; return; }
29     int mid=(L+R)>>1; push(x,L,R);
30     if (r<=mid) ins(v[y].ls,lson,l,r,k);
31     else if (l>mid) ins(v[y].rs,rson,l,r,k);
32         else ins(v[y].ls,lson,l,mid,k),ins(v[y].rs,rson,mid+1,r,k);
33     v[x].sm=v[v[x].ls].sm+v[v[x].rs].sm;
34 }
35 
36 ll que(int x,int L,int R,int l,int r){
37     if (L==l && r==R) return v[x].sm;
38     int mid=(L+R)>>1; push(x,L,R);
39     if (r<=mid) return que(lson,l,r);
40     else if (l>mid) return que(rson,l,r);
41         else return que(lson,l,mid)+que(rson,mid+1,r);
42 }
43 
44 int main(){
45     freopen("hdu4348.in","r",stdin);
46     freopen("hdu4348.out","w",stdout);
47     while (~scanf("%d%d",&n,&m)){
48         rep(i,1,n) scanf("%d",&a[i]);
49         nd=tim=0; build(rt[0],1,n);
50         rep(i,1,m){
51             scanf(" %c",&op);
52             if (op=='C') scanf("%d%d%d",&l,&r,&k),tim++,ins(rt[tim-1],rt[tim],1,n,l,r,k);
53             if (op=='Q') scanf("%d%d",&l,&r),printf("%lld\n",que(rt[tim],1,n,l,r));
54             if (op=='H') scanf("%d%d%d",&l,&r,&k),printf("%lld\n",que(rt[k],1,n,l,r));
55             if (op=='B') scanf("%d",&k),tim=k;
56         }
57         puts("");
58     }
59     return 0;
60 }
未永久化(MLE)

另一种写法就是标记永久化,若一个修改区间覆盖当前区间则将tag+=k,但并不下传。询问时将答案加上tag的贡献即可。

注意多组数据的清空问题。

 1 #include<cstdio>
 2 #include<algorithm>
 3 #define lson v[x].ls,L,mid
 4 #define rson v[x].rs,mid+1,R
 5 #define rep(i,l,r) for (int i=(l); i<=(r); i++)
 6 typedef long long ll;
 7 using namespace std;
 8 
 9 const int N=100010;
10 char op;
11 int n,m,l,r,k,tim,nd,flag,a[N],rt[N];
12 struct Tr{ int ls,rs; ll sm,tag; }v[N*25];
13 
14 void build(int &x,int L,int R){
15     x=++nd;
16     if (L==R){ v[x]=(Tr){0,0,a[L],0}; return; }
17     int mid=(L+R)>>1;
18     build(lson); build(rson);
19     v[x].sm=v[v[x].ls].sm+v[v[x].rs].sm; v[x].tag=0;
20 }
21 
22 void ins(int y,int &x,int L,int R,int l,int r,int k){
23     x=++nd; v[x]=v[y]; v[x].sm+=1ll*(r-l+1)*k;
24     if (L==l && r==R){ v[x].tag+=k; return; }
25     int mid=(L+R)>>1;
26     if (r<=mid) ins(v[y].ls,lson,l,r,k);
27     else if (l>mid) ins(v[y].rs,rson,l,r,k);
28         else ins(v[y].ls,lson,l,mid,k),ins(v[y].rs,rson,mid+1,r,k);
29 }
30 
31 ll que(int x,int L,int R,int l,int r){
32     if (L==l && r==R) return v[x].sm;
33     int mid=(L+R)>>1,res=v[x].tag*(r-l+1);
34     if (r<=mid) return res+que(lson,l,r);
35     else if (l>mid) return res+que(rson,l,r);
36         else return res+que(lson,l,mid)+que(rson,mid+1,r);
37 }
38 
39 int main(){
40     freopen("hdu4348.in","r",stdin);
41     freopen("hdu4348.out","w",stdout);
42     while (~scanf("%d%d",&n,&m)){
43         if (flag) puts(""); else flag=1;
44         rep(i,1,n) scanf("%d",&a[i]);
45         nd=tim=0; build(rt[0],1,n);
46         rep(i,1,m){
47             scanf(" %c",&op);
48             if (op=='C') scanf("%d%d%d",&l,&r,&k),tim++,ins(rt[tim-1],rt[tim],1,n,l,r,k);
49             if (op=='Q') scanf("%d%d",&l,&r),printf("%lld\n",que(rt[tim],1,n,l,r));
50             if (op=='H') scanf("%d%d%d",&l,&r,&k),printf("%lld\n",que(rt[k],1,n,l,r));
51             if (op=='B') scanf("%d",&tim);
52         }
53     }
54     return 0;
55 }

 

标签:int,scanf,d%,mid,moon,永久化,sm,HDU4348,rson
来源: https://www.cnblogs.com/HocRiser/p/10421619.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有