zoukankan      html  css  js  c++  java
  • [HDU4348]To the moon(主席树+标记永久化)

    学可持久化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
    ",que(rt[tim],1,n,l,r));
    54             if (op=='H') scanf("%d%d%d",&l,&r,&k),printf("%lld
    ",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
    ",que(rt[tim],1,n,l,r));
    50             if (op=='H') scanf("%d%d%d",&l,&r,&k),printf("%lld
    ",que(rt[k],1,n,l,r));
    51             if (op=='B') scanf("%d",&tim);
    52         }
    53     }
    54     return 0;
    55 }
  • 相关阅读:
    ActiveMQ 即时通讯服务 浅析
    Asp.net Mvc (Filter及其执行顺序)
    ActiveMQ基本介绍
    ActiveMQ持久化消息的三种方式
    Windows Azure Virtual Machine (27) 使用psping工具,测试Azure VM网络连通性
    Azure China (10) 使用Azure China SAS Token
    Windows Azure Affinity Groups (3) 修改虚拟网络地缘组(Affinity Group)的配置
    Windows Azure Storage (22) Azure Storage如何支持多级目录
    Windows Azure Virtual Machine (26) 使用高级存储(SSD)和DS系列VM
    Azure Redis Cache (2) 创建和使用Azure Redis Cache
  • 原文地址:https://www.cnblogs.com/HocRiser/p/10421619.html
Copyright © 2011-2022 走看看