• 2016shenyang-1002-HDU5893-List wants to travel-树链剖分+线段树维护不同区间段个数


    肯定先无脑树链剖分,然后线段树维护一段区间不同个数,再维护一个左右端点的费用。

    线段树更新,pushDown,pushUp的时候要注意考虑链接位置的费用是否相同

    还有就是树链剖分操作的时候,维护上一个更新的位置的费用。

    总之就是出现区间合并,就考虑总数是否要减一

    好想不好写

    //场上根本写不完啊

      1 /*--------------------------------------------------------------------------------------*/
      2 
      3 #include <algorithm>
      4 #include <iostream>
      5 #include <cstring>
      6 #include <ctype.h>
      7 #include <cstdlib>
      8 #include <cstdio>
      9 #include <vector>
     10 #include <string>
     11 #include <queue>
     12 #include <stack>
     13 #include <cmath>
     14 #include <set>
     15 #include <map>
     16 
     17 //debug function for a N*M array
     18 #define debug_map(N,M,G) printf("
    ");for(int i=0;i<(N);i++)
     19 {for(int j=0;j<(M);j++){
     20 printf("%d",G[i][j]);}printf("
    ");}
     21 //debug function for int,float,double,etc.
     22 #define debug_var(X) cout<<#X"="<<X<<endl;
     23 #define LL long long
     24 const int INF = 0x3f3f3f3f;
     25 const LL LLINF = 0x3f3f3f3f3f3f3f3f;
     26 /*--------------------------------------------------------------------------------------*/
     27 using namespace std;
     28 
     29 int N,M,T;
     30 const int maxn = 2e5+100;
     31 
     32 struct Edge{
     33     int x,y,val;
     34 }e[maxn];
     35 
     36 vector <int> G[maxn];
     37 
     38 int val[maxn],dep[maxn],siz[maxn],top[maxn],id[maxn],son[maxn],fa[maxn];
     39 int topw;
     40 
     41 void init()
     42 {
     43     for(int i=0;i<maxn;i++) G[i].clear();
     44     topw = 0;
     45 }
     46 
     47 void dfs_1(int u,int f,int d)
     48 {
     49     fa[u] = f;
     50     son[u] = 0;
     51     siz[u] = 1;
     52     dep[u] = d;
     53     for(int i=0;i<G[u].size();i++) if(G[u][i] != f)
     54     {
     55         dfs_1(G[u][i],u,d+1);
     56         siz[u] += siz[G[u][i]];
     57         if(siz[son[u]] < siz[G[u][i] ])
     58         {
     59             son[u] = G[u][i];
     60         }
     61     }
     62 }
     63 
     64 void dfs_2(int u,int tp)
     65 {
     66     top[u] = tp;
     67     id[u] = ++topw;
     68     if(son[u]) dfs_2(son[u],tp);
     69     for(int i=0;i<G[u].size();i++) if(G[u][i]!=fa[u] && G[u][i] != son[u] )
     70     {
     71         dfs_2(G[u][i],G[u][i]);
     72     }
     73 }
     74 
     75 void debug()
     76 {
     77     for(int i=1;i<=N;i++)
     78     {
     79         printf("%d siz:%d son:%d dep:%d fa:%d ",i,siz[i],son[i],dep[i],fa[i]);
     80         printf("top:%d id:%d
    ",top[i],id[i]);
     81     }
     82     return ;
     83 }
     84 
     85 /*-----------------------------------*/
     86 #define lson(x) (x<<1)
     87 #define rson(x) (x<<1|1)
     88 
     89 struct SegmentTree{
     90     int l,r;
     91     int lazy;
     92     int num,lcost,rcost;
     93 }segtree[4*maxn];
     94 
     95 void pushUp(int x)
     96 {
     97     segtree[x].num = segtree[lson(x)].num + segtree[rson(x)].num - (segtree[lson(x)].rcost==segtree[rson(x)].lcost? 1 : 0);
     98     segtree[x].lcost = segtree[lson(x)].lcost;
     99     segtree[x].rcost = segtree[rson(x)].rcost;
    100     //printf("x:%d [%d,%d] num:%d
    ",x,segtree[x].l,segtree[x].r,segtree[x].num);
    101     //printf("lcost:%d rcost:%d
    ",segtree[x].lcost,segtree[x].rcost);
    102     //printf("l->rcost:%d r->lcost:%d
    ",segtree[lson(x)].rcost,segtree[rson(x)].lcost);
    103 }
    104 
    105 void pushDown(int x)
    106 {
    107     if(segtree[x].lazy != -1)
    108     {
    109         segtree[lson(x)].lcost = segtree[lson(x)].rcost = segtree[x].lazy;
    110         segtree[rson(x)].lcost = segtree[rson(x)].rcost = segtree[x].lazy;
    111         segtree[lson(x)].num = segtree[rson(x)].num = 1;
    112         segtree[lson(x)].lazy = segtree[rson(x)].lazy = segtree[x].lazy;
    113         segtree[x].lazy = -1;
    114     }
    115 }
    116 
    117 void Build(int l,int r,int x)
    118 {
    119     segtree[x].l = l;
    120     segtree[x].r = r;
    121     segtree[x].lazy = -1;
    122     if(l == r)
    123     {
    124         segtree[x].num = 1;
    125         segtree[x].lcost = segtree[x].rcost = val[l];
    126         return ;
    127     }
    128     int mid = (l+r)>>1;
    129     Build(l,mid,lson(x));
    130     Build(mid+1,r,rson(x));
    131     pushUp(x);
    132 }
    133 
    134 void update(int x,int L,int R,int cost)
    135 {
    136     if(segtree[x].l >= L && segtree[x].r <= R)
    137     {
    138         segtree[x].lcost = segtree[x].rcost = cost;
    139         segtree[x].num = 1;
    140         segtree[x].lazy = cost;
    141         return ;
    142     }
    143     pushDown(x);
    144     int mid = (segtree[x].l + segtree[x].r) >> 1;
    145     if(L <= mid) update(lson(x),L,R,cost);
    146     if(R >  mid) update(rson(x),L,R,cost);
    147     pushUp(x);
    148     return ;
    149 }
    150 
    151 int query(int x,int L,int R)
    152 {
    153     if(segtree[x].l >= L && segtree[x].r <= R)
    154     {
    155         return segtree[x].num;
    156     }
    157     pushDown(x);
    158     int mid = (segtree[x].l + segtree[x].r) >> 1;
    159     int ans = 0;
    160 
    161     if(R <= mid) ans = query(lson(x),L,R);
    162     else if(L > mid) ans = query(rson(x),L,R);
    163     else ans = query(lson(x),L,R) + query(rson(x),L,R) - (segtree[lson(x)].rcost==segtree[rson(x)].lcost ? 1 : 0) ;
    164     pushUp(x);
    165     return ans;
    166 }
    167 
    168 int query_edge(int x,int pos)
    169 {
    170     if(segtree[x].l == segtree[x].r)
    171     {
    172         return segtree[x].lcost;
    173     }
    174     pushDown(x);
    175     int res = 0;
    176     int mid = (segtree[x].l + segtree[x].r) >> 1;
    177     if(pos <= mid) res =  query_edge(lson(x),pos);
    178     else           res =  query_edge(rson(x),pos);
    179     pushUp(x);
    180     return res ;
    181 }
    182 
    183 int Find(int u,int v)
    184 {
    185     int ans = 0,fu = top[u],fv = top[v];
    186     int last_u=-1 , last_v = -1;
    187     int last_u_color,last_v_color;
    188     //printf("%d->%d
    ",u,v);
    189 
    190     while(fu != fv)
    191     {
    192         if(dep[fu] < dep[fv])
    193         {
    194             swap(fu,fv);swap(u,v);
    195             swap(last_u,last_v);
    196             swap(last_u_color,last_v_color);
    197         }
    198 
    199         //printf("query:[%d,%d] %d->%d ",id[fu],id[u],u,fu);
    200         //printf("%d
    ",query(1,id[fu],id[u]));
    201         ans += query(1,id[fu],id[u]);
    202         if(last_u == -1)
    203         {
    204             last_u = fu;
    205             last_u_color = query_edge(1,id[fu]);
    206         }
    207         else
    208         {
    209             if(last_u != -1 && fa[last_u] == u)
    210             {
    211                 //printf("u sub:%d
    ",(last_u_color==query_edge(1,id[u]) ? 1 : 0));
    212                 ans -= (last_u_color==query_edge(1,id[u]) ? 1 : 0);
    213                 last_u = fu;
    214                 last_u_color = query_edge(1,id[fu]);
    215             }
    216         }
    217         u = fa[fu];
    218         fu = top[u];
    219     }
    220     if(u == v)
    221     {
    222         if(last_u != -1 && last_v != -1 && last_u_color==last_v_color) ans -= 1;
    223         return ans;
    224     }
    225     if(dep[u] < dep[v])
    226     {
    227         swap(u,v);
    228         swap(last_u,last_v);
    229         swap(last_u_color,last_v_color);
    230     }
    231     //printf("query:[%d,%d] %d->%d ",id[son[v]],id[u],u,son[v]);
    232     ans += query(1,id[son[v] ],id[u]);
    233     //printf("%d*
    ",query(1,id[son[v]],id[u]));
    234 
    235     //printf("last_u:%d last_v:%d
    ",last_u,last_v);
    236     if(last_u != -1 && fa[last_u] == u)
    237     {
    238         //printf("u sub:%d last_u_color:%d u_color:%d
    ",(last_u_color==query_edge(1,id[u]) ? 1 : 0),last_u_color,query_edge(1,id[u]));
    239         ans -= (last_u_color==query_edge(1,id[u]) ? 1 : 0);
    240         last_u = fu;
    241         last_u_color = query_edge(1,id[u]);
    242     }
    243 
    244     if(last_v != -1 && fa[last_v] == v)
    245     {
    246         //printf("v sub:%d last_v_color:%d son[v]_color:%d
    ",(last_v_color==query_edge(1,id[son[v]]) ? 1 : 0),last_v_color,query_edge(1,id[son[v]] ));
    247         ans -= (last_v_color==query_edge(1,id[son[v]]) ? 1 : 0);
    248         last_v = fv;
    249         last_v_color = query_edge(1,id[son[v]]);
    250     }
    251 
    252     return ans;
    253 }
    254 
    255 void Change(int u,int v,int cost)
    256 {
    257     int fu = top[u],fv = top[v];
    258     //printf("%d->%d
    ",u,v);
    259     while(fu != fv)
    260     {
    261         if(dep[fu] < dep[fv])
    262         {
    263             swap(fu,fv);swap(u,v);
    264         }
    265         //printf("change:[%d,%d] %d->%d %d
    ",id[fu],id[u],u,fu,cost);
    266         update(1,id[fu],id[u],cost);
    267         u = fa[fu];
    268         fu = top[u];
    269     }
    270     if(u == v) return ;
    271     if(dep[u] < dep[v]) swap(u,v);
    272     //printf("change:[%d,%d] %d->%d %d
    ",id[son[v]],id[u],u,son[u],cost);
    273     update(1,id[son[v]],id[u],cost);
    274     return ;
    275 }
    276 
    277 int main()
    278 {
    279     //freopen("input","r",stdin);
    280     while(~scanf("%d%d",&N,&M))
    281     {
    282         init();
    283         int u,v,w;
    284         for(int i=1;i<N;i++)
    285         {
    286             scanf("%d%d%d",&u,&v,&w);
    287             e[i].x = u;e[i].y = v;e[i].val = w;
    288             G[u].push_back(v);
    289             G[v].push_back(u);
    290         }
    291         topw = 0;
    292         dfs_1(1,0,1);
    293         dfs_2(1,1);
    294         //debug();
    295         for(int i=1;i<N;i++)
    296         {
    297             if(dep[e[i].x] < dep[e[i].y]) swap(e[i].x,e[i].y);
    298             val[id[e[i].x]] = e[i].val;
    299         }
    300 
    301         Build(1,topw,1);
    302         char op[20];
    303         //printf("-----------------
    ");
    304         for(int i=0;i<M;i++)
    305         {
    306             scanf("%s",op);
    307             if(op[0] == 'Q')
    308             {
    309                 scanf("%d%d",&u,&v);
    310                 printf("%d
    ",Find(u,v));
    311             }
    312             else
    313             {
    314                 scanf("%d%d%d",&u,&v,&w);
    315                 Change(u,v,w);
    316             }
    317             //puts("");
    318         }
    319     }
    320 }
  • 相关阅读:
    maven的pom.xml文件详细说明
    python 给视频添加马赛克
    cv2.VideoCapture 图像旋转问题
    三分钟理解知识蒸馏
    深度学习、机器学习常见概念及理解(持续更新)
    python用直方图规定化实现图像风格转换
    1分钟理解人体姿态估计与行为识别
    数据清洗要点
    3分钟理解NMS非极大值抑制
    python用pandas遍历csv文件
  • 原文地址:https://www.cnblogs.com/helica/p/5890263.html
Copyright © 2020-2023  润新知