zoukankan      html  css  js  c++  java
  • 2018-8-10 模拟赛T3(可持久化线段树)

    出题人说:正解离线按DFS序排序线段维护区间和

    但是对于树上每个点都有一个区间和一个值,两个点之间求1~m的区间和,这不就是用可持久化线段树吗。

    只不过这个线段树需要区间修改,不过不需要标记下传,询问时加起来就好了。

    对于每一个节点x,建一个1~m的线段树版本

    询问时,先求出u和v的lca和lca的父亲flca

    询问在{u+v}和{lca,flca}的差集中的区间和就好了

    可持久化数据结构耗费的空间是巨大的^_^

      1 #include<cstdio>
      2 #include<cstring>
      3 #include<algorithm>
      4 using namespace std;
      5 typedef long long lnt;
      6 struct pnt{
      7     int hd;
      8     int a;
      9     int b;
     10     int oul;
     11     int fa;
     12     int dp;
     13     lnt w;
     14     int root;
     15 }p[200000];
     16 struct ent{
     17     int twd;
     18     int lst;
     19 }e[1000000];
     20 struct tree{
     21     int l,r;
     22     lnt val;
     23     lnt laz;
     24 };
     25 struct Traos{
     26     tree tr[8000000];
     27     int siz;
     28     int ks;
     29     lnt ansl;
     30     void build(int l,int r,int &spc)
     31     {
     32         if(!spc)
     33             spc=++siz;
     34         if(l==r)
     35             return ;
     36         int md=(l+r)/2;
     37         build(l,md,tr[spc].l);
     38         build(md+1,r,tr[spc].r);
     39     }    
     40     void updte(int &spc,int last,int ll,int rr,int l,int r,lnt v)
     41     {
     42         if(l>rr||r<ll)
     43             return ;
     44         spc=++siz;
     45         tr[spc]=tr[last];
     46         if(ll<=l&&rr>=r)
     47         {
     48             tr[spc].val+=(lnt)(r-l+1)*v;
     49             tr[spc].laz+=v;
     50             return ;
     51         }
     52         tr[spc].val+=(lnt)(min(rr,r)-max(l,ll)+1)*v;
     53         int mid=(l+r)/2;
     54         updte(tr[spc].l,tr[last].l,ll,rr,l,mid,v);
     55         updte(tr[spc].r,tr[last].r,ll,rr,mid+1,r,v);
     56         return ;
     57     }
     58     lnt sumls(int spc1,int spc2,int ll,int rr,int l,int r)
     59     {
     60         if(l>rr||ll>r)
     61             return 0ll;
     62         if(ll<=l&&rr>=r)
     63             return (lnt)(tr[spc2].val-tr[spc1].val);
     64         int mid=(l+r)/2;
     65         return (lnt)((lnt)(min(rr,r)-max(ll,l)+1)*(tr[spc2].laz-tr[spc1].laz))+sumls(tr[spc1].l,tr[spc2].l,ll,rr,l,mid)+sumls(tr[spc1].r,tr[spc2].r,ll,rr,mid+1,r);
     66             
     67     }
     68 }T;
     69 int cnt;
     70 int ont;
     71 int n,m,q;
     72 int ola[20][500000];
     73 int rt[100001];
     74 int lg[500000];
     75 void ade(int f,int t)
     76 {
     77     cnt++;
     78     e[cnt].lst=p[f].hd;
     79     e[cnt].twd=t;
     80     p[f].hd=cnt;
     81 }
     82 void dfs(int x,int f)
     83 {
     84     p[x].fa=f;
     85     p[x].dp=p[f].dp+1;
     86     p[x].oul=++ont;
     87     ola[0][ont]=x;
     88     for(int i=p[x].hd;i;i=e[i].lst)
     89     {
     90         int to=e[i].twd;
     91         if(to!=f)
     92         {
     93             dfs(to,x);
     94             ola[0][++ont]=x;
     95         }
     96     }
     97 }
     98 int mxs(int a,int b)
     99 {
    100     return p[a].dp<p[b].dp?a:b;
    101 }
    102 void kls()
    103 {
    104     for(int i=1;i<=18;i++)
    105     {
    106         for(int j=1;j+(1<<i)-1<=ont;j++)
    107         {
    108             ola[i][j]=mxs(ola[i-1][j],ola[i-1][j+(1<<(i-1))]);
    109         }
    110     }
    111 }
    112 int lca(int a,int b)
    113 {
    114     if(p[a].oul>p[b].oul)
    115         swap(a,b);
    116     int lgg=lg[p[b].oul-p[a].oul+1];
    117     return mxs(ola[lgg][p[a].oul],ola[lgg][p[b].oul-(1<<lgg)+1]);
    118 }
    119 void fdfs(int x,int f)
    120 {
    121     p[x].root=++T.ks;
    122     T.updte(rt[p[x].root],rt[p[f].root],p[x].a,p[x].b,1,m,p[x].w);
    123     for(int i=p[x].hd;i;i=e[i].lst)
    124     {
    125         int to=e[i].twd;
    126         if(to-f)
    127         {
    128             fdfs(to,x);
    129         }
    130     }
    131 }
    132 int main()
    133 {
    134     freopen("c.in","r",stdin);
    135     freopen("c.out","w",stdout);
    136     scanf("%d%d%d",&n,&m,&q);
    137     for(int i=2;i<=3*n;i++)
    138     {
    139         lg[i]=lg[i/2]+1;
    140     }
    141     for(int i=1;i<n;i++)
    142     {
    143         int x,y;
    144         scanf("%d%d",&x,&y);
    145         ade(x,y);
    146         ade(y,x);
    147     }    
    148     for(int i=1;i<=n;i++)
    149     {
    150         scanf("%d%d%d",&p[i].a,&p[i].b,&p[i].w);
    151         p[i].a=min(p[i].a,p[i].b);
    152         p[i].b=max(p[i].a,p[i].b);
    153     }
    154     dfs(1,0);
    155     kls();
    156     T.build(1,m,rt[0]);
    157     fdfs(1,0);
    158     for(int i=1;i<=q;i++)
    159     {
    160         int u,v,l,r;
    161         scanf("%d%d%d%d",&u,&v,&l,&r);
    162         l=min(l,r);
    163         r=max(l,r);
    164         int la=lca(u,v);
    165         lnt ans=0;
    166         int fl=p[la].fa;
    167         ans=T.sumls(rt[p[la].root],rt[p[u].root],l,r,1,m);
    168         ans+=T.sumls(rt[p[fl].root],rt[p[v].root],l,r,1,m);
    169         printf("%lld
    ",ans);
    170     }
    171     return 0;
    172 }
  • 相关阅读:
    如何在Android平台下进行Socket通信
    通过 按钮 bundle 传过来 变换Q币图片
    Android中focusable属性的妙用——底层按钮的实现
    Android与服务器交互的简单例子
    Microsoft Office SharePoint Server 2007介绍
    mathtype使用
    VS2010快捷键
    xxd
    gas 多文件组织
    612 根目录下vmlinux , compressed下的vmlinux,boot下的Image、zImage
  • 原文地址:https://www.cnblogs.com/blog-Dr-J/p/9458096.html
Copyright © 2011-2022 走看看