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 }
  • 相关阅读:
    Zabbix安装部署
    设计模式目录导航
    [内排序]八大经典排序合集
    SpringBoot集成基于tobato的fastdfs-client实现文件上传下载和删除
    Docker部署FastDFS(附示例代码)
    Docker部署Portainer搭建轻量级可视化管理UI
    Maven基础知识详解
    SpringBoot整合Swagger2详细教程
    screw一键生成数据库文档
    SpringBoot + Mybatis-Plus 实现多数据源简单示例
  • 原文地址:https://www.cnblogs.com/HocRiser/p/10421619.html
Copyright © 2011-2022 走看看