zoukankan      html  css  js  c++  java
  • bzoj3307雨天的尾巴(权值线段树合并/DSU on tree)

    题目大意:

    一颗树,想要在树链上添加同一物品,问最后每个点上哪个物品最多。

    解题思路:

    1.线段树合并

    假如说物品数量少到可以暴力添加,且树点极少,我们怎么做。

    首先在一个树节点上标记出哪些物品有多少,寻找道路上的节点暴力添加。

    而如果节点比较多,我们使用树上差分u+1,v+1,lca-1,fa[lca]-1向上求和就得到了答案

    而颜色较多呢,和刚才唯一不同就在于向上求和时不要用数组,用线段树合并就好了(记录线段树区间的最大值与最大位置)

    废点的回收是非常实用的^_^

    时间复杂度O(nlogn)

    代码:

      1 #include<queue>
      2 #include<cstdio>
      3 #include<cstring>
      4 #include<algorithm>
      5 #define lll tr[spc].ls
      6 #define rrr tr[spc].rs
      7 const int maxin=1000000000;
      8 struct pnt{
      9     int fa[20];
     10     int hd;
     11     int gd;
     12     int dp;
     13     int wgt;
     14     int ans;
     15     int prp;
     16     int root;
     17 }p[110000];
     18 struct ent{
     19     int twd;
     20     int lst;
     21 }e[220000];
     22 struct ljt{
     23     int twd;
     24     int lst;
     25     int vls;
     26 }el[420000];
     27 struct trnt{
     28     int ls;
     29     int rs;
     30     int val;
     31     int mpl;
     32 }tr[2000000],org;
     33 int bin[2000000];
     34 int top;
     35 int siz;
     36 int cnt1;
     37 int cnt2;
     38 int n,m;
     39 void adde(int f,int t)
     40 {
     41     cnt1++;
     42     e[cnt1].twd=t;
     43     e[cnt1].lst=p[f].hd;
     44     p[f].hd=cnt1;
     45     return ;
     46 }
     47 void addc(int pt,int c,int v)
     48 {
     49     cnt2++;
     50     el[cnt2].twd=c;
     51     el[cnt2].lst=p[pt].gd;
     52     el[cnt2].vls=v;
     53     p[pt].gd=cnt2;
     54     return ;
     55 }
     56 namespace Sgt{
     57     void P_delete(int spc)
     58     {
     59         bin[++top]=spc;
     60         tr[spc]=org;
     61         return ;
     62     }
     63     void P_destory(int spc1,int spc2)
     64     {
     65         P_delete(spc1);
     66         P_delete(spc2);
     67         return ;
     68     }
     69     int P_new(void)
     70     {
     71         if(top)
     72             return bin[top--];
     73         return ++siz;
     74     }
     75     void pushup(int spc)
     76     {
     77         if(tr[lll].val>=tr[rrr].val)
     78             tr[spc].val=tr[lll].val,tr[spc].mpl=tr[lll].mpl;
     79         else
     80             tr[spc].val=tr[rrr].val,tr[spc].mpl=tr[rrr].mpl;
     81         return ;
     82     }
     83     int P_merge(int spc1,int spc2,int l,int r)
     84     {
     85         if(!spc1||!spc2)
     86             return spc1+spc2;
     87         int spc=P_new();
     88         if(l==r)
     89         {
     90             tr[spc].val=tr[spc1].val+tr[spc2].val;
     91             tr[spc].mpl=l;
     92             P_destory(spc1,spc2);
     93             return spc;
     94         }
     95         int mid=(l+r)>>1;
     96         tr[spc].ls=P_merge(tr[spc1].ls,tr[spc2].ls,l,mid);
     97         tr[spc].rs=P_merge(tr[spc1].rs,tr[spc2].rs,mid+1,r);
     98         pushup(spc);
     99         P_destory(spc1,spc2);
    100         return spc;
    101     }
    102     void Update(int l,int r,int &spc,int pos,int v)
    103     {
    104         if(!spc)
    105             spc=P_new();
    106         if(l==r)
    107         {
    108             tr[spc].val+=v;
    109             tr[spc].mpl=(tr[spc].val)?l:0;
    110             return ;
    111         }
    112         int mid=(l+r)>>1;
    113         if(pos<=mid)
    114             Update(l,mid,tr[spc].ls,pos,v);
    115         else
    116             Update(mid+1,r,tr[spc].rs,pos,v);
    117         pushup(spc);
    118         if(!tr[spc].val)
    119             tr[spc].mpl=0;
    120         return ;
    121     }
    122 }
    123 void Basic_dfs(int x,int f)
    124 {
    125     p[x].dp=p[f].dp+1;
    126     p[x].fa[0]=f;
    127     for(int i=1;i<=19;i++)
    128         p[x].fa[i]=p[p[x].fa[i-1]].fa[i-1];
    129     p[x].wgt=1;
    130     for(int i=p[x].hd;i;i=e[i].lst)
    131     {
    132         int to=e[i].twd;
    133         if(to==f)
    134             continue;
    135         Basic_dfs(to,x);
    136         p[x].wgt+=p[to].wgt;
    137     }
    138     return ;
    139 }
    140 void Ans_dfs(int x,int f)
    141 {
    142     for(int i=p[x].hd;i;i=e[i].lst)
    143     {
    144         int to=e[i].twd;
    145         if(to==f)
    146             continue;
    147         Ans_dfs(to,x);
    148     }
    149     for(int i=p[x].gd;i;i=el[i].lst)
    150     {
    151         int clr=el[i].twd;
    152         Sgt::Update(1,maxin,p[x].root,clr,el[i].vls);
    153     }
    154     p[x].ans=tr[p[x].root].mpl;
    155     p[f].root=Sgt::P_merge(p[f].root,p[x].root,1,maxin);
    156 }
    157 int Lca(int x,int y) 
    158 {
    159     if(p[x].dp<p[y].dp)
    160         std::swap(x,y);
    161     for(int i=19;i>=0;i--)
    162         if(p[p[x].fa[i]].dp>=p[y].dp)
    163             x=p[x].fa[i];
    164     if(x==y)
    165         return x;
    166     for(int i=19;i>=0;i--)
    167         if(p[x].fa[i]!=p[y].fa[i])
    168             x=p[x].fa[i],y=p[y].fa[i];
    169     return p[x].fa[0];
    170 }
    171 int main()
    172 {
    173     scanf("%d%d",&n,&m);
    174     for(int i=1;i<n;i++)
    175     {
    176         int a,b;
    177         scanf("%d%d",&a,&b);
    178         adde(a,b);
    179         adde(b,a);
    180     }
    181     Basic_dfs(1,1);
    182     for(int i=1;i<=m;i++)
    183     {
    184         int x,y,z;
    185         scanf("%d%d%d",&x,&y,&z);
    186         addc(x,z,1);
    187         addc(y,z,1);
    188         int lca=Lca(x,y);
    189         addc(lca,z,-1);
    190         if(lca!=1)
    191             addc(p[lca].fa[0],z,-1);
    192     }
    193     Ans_dfs(1,1);
    194     for(int i=1;i<=n;i++)
    195         printf("%d
    ",p[i].ans);
    196     return 0;
    197 }

     2.DSU on tree

    如同经典的DSU on tree,重链剖分,对轻儿子暴力修改,只不过使用权值线段树而不是桶,时间复杂度O(nlog2n),慢了点常数也大,但数据105还是没有问题的

    代码:

      1 #include<cstdio>
      2 #include<cstring>
      3 #include<algorithm>
      4 #define lll spc<<1
      5 #define rrr spc<<1|1
      6 const int maxc=100000;
      7 struct pnt{
      8     int hd;
      9     int gd;
     10     int fa;
     11     int tp;
     12     int dp;
     13     int wgt;
     14     int mxs;
     15     int ans;
     16 }p[1000000];
     17 struct ent{
     18     int twd;
     19     int lst;
     20 }e[1000000];
     21 struct clr{
     22     int twd;
     23     int lst;
     24     int vls;
     25 }c[1000000];
     26 struct trnt{
     27     int val;
     28     int maxp;
     29 }tr[10000000],stdtr;
     30 int n,m;
     31 int cnt;
     32 int clt;
     33 void ade(int f,int t)
     34 {
     35     cnt++;
     36     e[cnt].twd=t;
     37     e[cnt].lst=p[f].hd;
     38     p[f].hd=cnt;
     39 }
     40 void adc(int f,int t,int v)
     41 {
     42     clt++;
     43     c[clt].twd=t;
     44     c[clt].lst=p[f].gd;
     45     c[clt].vls=v;
     46     p[f].gd=clt;
     47 }
     48 void pushup(int spc)
     49 {
     50     if(tr[lll].val>=tr[rrr].val)
     51         tr[spc]=tr[lll];
     52     else
     53         tr[spc]=tr[rrr];
     54 }
     55 void update(int l,int r,int spc,int pos,int v)
     56 {
     57     if(l==r)
     58     {
     59         tr[spc].val+=v;
     60         tr[spc].maxp=pos;
     61         if(!tr[spc].val)
     62             tr[spc].maxp=0;
     63         return ;
     64     }
     65     int mid=(l+r)>>1;
     66     if(pos<=mid)
     67         update(l,mid,lll,pos,v);
     68     else
     69         update(mid+1,r,rrr,pos,v);
     70     pushup(spc);
     71     return ;
     72 }
     73 void Destroy(int l,int r,int spc)
     74 {
     75     tr[spc]=stdtr;
     76     if(l==r)
     77         return ;
     78     int mid=(l+r)>>1;
     79     Destroy(l,mid,lll);
     80     Destroy(mid+1,r,rrr);
     81     return ;
     82 }
     83 int Lca(int x,int y)
     84 {
     85     while(p[x].tp!=p[y].tp)
     86     {
     87         if(p[p[x].tp].dp<p[p[y].tp].dp)
     88             std::swap(x,y);
     89         x=p[p[x].tp].fa;
     90     }
     91     if(p[x].dp>p[y].dp)
     92         std::swap(x,y);
     93     return x;
     94 }
     95 void Basic_dfs(int x,int f)
     96 {
     97     int maxs=-1;
     98     p[x].wgt=1;
     99     p[x].dp=p[f].dp+1;
    100     p[x].fa=f;
    101     for(int i=p[x].hd;i;i=e[i].lst)
    102     {
    103         int to=e[i].twd;
    104         if(to==f)
    105             continue;
    106         Basic_dfs(to,x);
    107         p[x].wgt+=p[to].wgt;
    108         if(p[to].wgt>maxs)
    109         {
    110             maxs=p[to].wgt;
    111             p[x].mxs=to;
    112         }
    113     }
    114     return ;
    115 }
    116 void Sec_dfs(int x,int f,int top)
    117 {
    118     if(!x)
    119         return ;
    120     p[x].tp=top;
    121     Sec_dfs(p[x].mxs,x,top);
    122     for(int i=p[x].hd;i;i=e[i].lst)
    123     {
    124         int to=e[i].twd;
    125         if(!p[to].tp)
    126             Sec_dfs(to,x,to);
    127     }
    128     
    129 }
    130 void Add_dfs(int x,int f)
    131 {
    132     for(int i=p[x].gd;i;i=c[i].lst)
    133         update(1,maxc,1,c[i].twd,c[i].vls);
    134     for(int i=p[x].hd;i;i=e[i].lst)
    135         if(e[i].twd!=f)
    136             Add_dfs(e[i].twd,x);
    137 }
    138 void Des_dfs(int x,int f)
    139 {
    140     for(int i=p[x].gd;i;i=c[i].lst)
    141         update(1,maxc,1,c[i].twd,-c[i].vls);
    142     for(int i=p[x].hd;i;i=e[i].lst)
    143         if(e[i].twd!=f)
    144             Des_dfs(e[i].twd,x);
    145 }
    146 void DSU_dfs(int x,int f,bool hv)
    147 {
    148     if(!x)
    149         return ;
    150     for(int i=p[x].hd;i;i=e[i].lst)
    151     {
    152         int to=e[i].twd;
    153         if(to==f||to==p[x].mxs)
    154             continue;
    155         DSU_dfs(to,x,false);
    156     }
    157     DSU_dfs(p[x].mxs,x,true);
    158     for(int i=p[x].hd;i;i=e[i].lst)
    159     {
    160         int to=e[i].twd;
    161         if(to==f||to==p[x].mxs)
    162             continue;
    163         Add_dfs(to,x);
    164     }
    165     for(int i=p[x].gd;i;i=c[i].lst)
    166         update(1,maxc,1,c[i].twd,c[i].vls);
    167     p[x].ans=tr[1].maxp;
    168     if(!hv)
    169         Des_dfs(x,f);
    170 }
    171 int main()
    172 {
    173     scanf("%d%d",&n,&m);
    174     for(int i=1;i<n;i++)
    175     {
    176         int a,b;
    177         scanf("%d%d",&a,&b);
    178         ade(a,b);
    179         ade(b,a);
    180     }
    181     Basic_dfs(1,1);
    182     Sec_dfs(1,1,1);
    183     for(int i=1;i<=m;i++)
    184     {
    185         int x,y,z;
    186         scanf("%d%d%d",&x,&y,&z);
    187         int l=Lca(x,y);
    188         adc(x,z,1);
    189         adc(y,z,1);
    190         adc(l,z,-1);
    191         if(l!=1)
    192             adc(p[l].fa,z,-1);
    193     }
    194     DSU_dfs(1,1,1);
    195     for(int i=1;i<=n;i++)
    196     {
    197         printf("%d
    ",p[i].ans);
    198     }
    199     return 0;
    200 }
  • 相关阅读:
    证券市场主体
    证券投资基金
    1.监控系统的重要性
    1.五种世界顶级思维-20190303
    【四校联考】【比赛题解】FJ NOIP 四校联考 2017 Round 7
    【学长出题】【比赛题解】17-09-29
    【codeforces】【比赛题解】#854 CF Round #433 (Div.2)
    【codeforces】【比赛题解】#851 CF Round #432 (Div.2)
    【算法学习】三分法
    【codeforces】【比赛题解】#849 CF Round #431 (Div.2)
  • 原文地址:https://www.cnblogs.com/blog-Dr-J/p/9589142.html
Copyright © 2011-2022 走看看