• HDU 4897 Little Devil I


    Little Devil I

    Time Limit: 8000ms
    Memory Limit: 131072KB
    This problem will be judged on HDU. Original ID: 4897
    64-bit integer IO format: %I64d      Java class name: Main
    There is an old country and the king fell in love with a devil. The devil always asks the king to do some crazy things. Although the king used to be wise and beloved by his people. Now he is just like a boy in love and can’t refuse any request from the devil. Also, this devil is looking like a very cute Loli.

    The devil likes to make thing in chaos. This kingdom’s road system is like simply a tree(connected graph without cycle). A road has a color of black or white. The devil often wants to make some change of this system.

    In details, we call a path on the tree from a to b consists of vertices lie on the shortest simple path between a and b. And we say an edge is on the path if both its two endpoints is in the path, and an edge is adjacent to the path if exactly one endpoint of it is in the path.

    Sometimes the devil will ask you to reverse every edge’s color on a path or adjacent to a path.

    The king’s daughter, WJMZBMR, is also a cute loli, she is surprised by her father’s lolicon-like behavior. As she is concerned about the road-system’s status, sometimes she will ask you to tell there is how many black edge on a path.

    Initially, every edges is white.
     

    Input

    The first line contains an integer T, denoting the number of the test cases.
    For each test case, the first line contains an integer n, which is the size of the tree. The vertices be indexed from 1.
    On the next n-1 lines, each line contains two integers a,b, denoting there is an edge between a and b. 
    The next line contains an integer Q, denoting the number of the operations.
    On the next Q lines, each line contains three integers t,a,b. t=1 means we reverse every edge’s color on path a to b. t=2 means we reverse every edge’s color adjacent to path a to b. t=3 means we query about the number of black edge on path a to b.

    T<=5.
    n,Q<=105.
    Please use scanf,printf instead of cin,cout,because of huge input.
     

    Output

    For each t=3 operation, output the answer in one line.
     

    Sample Input

    1
    10
    2 1
    3 1
    4 1
    5 1
    6 5
    7 4
    8 3
    9 5
    10 6
    
    10
    2 1 6
    1 3 8
    3 8 10
    2 3 4
    2 10 8
    2 4 10
    1 7 6
    2 7 3
    2 1 4
    2 10 10

    Sample Output

    3

    Hint

    reverse color means change from white to black or vice virsa.
     

    Source

     
    解题:树链剖分
      1 #include <bits/stdc++.h>
      2 using namespace std;
      3 const int maxn = 101010;
      4 struct arc {
      5     int to,next;
      6     arc(int x = 0,int y = -1) {
      7         to = x;
      8         next = y;
      9     }
     10 } e[maxn<<1];
     11 int head[maxn],cnt,tot;
     12 void add(int u,int v) {
     13     e[tot] = arc(v,head[u]);
     14     head[u] = tot++;
     15 }
     16 int dep[maxn],fa[maxn],top[maxn],siz[maxn],son[maxn];
     17 int loc[maxn],sum[maxn<<2],flip[maxn<<2],light[maxn<<2];
     18 void FindHeavyEdge(int u,int father,int depth) {
     19     dep[u] = depth;
     20     fa[u] = father;
     21     siz[u] = 1;
     22     son[u] = -1;
     23     for(int i = head[u]; ~i; i = e[i].next) {
     24         if(e[i].to == father) continue;
     25         FindHeavyEdge(e[i].to,u,depth + 1);
     26         siz[u] += siz[e[i].to];
     27         if(son[u] == -1 || siz[son[u]] < siz[e[i].to])
     28             son[u] = e[i].to;
     29     }
     30 }
     31 void ConnectHeavyEdge(int u,int ancestor){
     32     top[u] = ancestor;
     33     loc[u] = ++cnt;
     34     if(~son[u]) ConnectHeavyEdge(son[u],ancestor);
     35     for(int i = head[u]; ~i; i = e[i].next){
     36         if(e[i].to == fa[u] || e[i].to == son[u]) continue;
     37         ConnectHeavyEdge(e[i].to,e[i].to);
     38     }
     39 }
     40 inline void pushdown(int v,int L,int M,int R){
     41     if(flip[v]){
     42         flip[v<<1] ^= 1;
     43         flip[v<<1|1] ^= 1;
     44         sum[v<<1] = (M - L + 1) - sum[v<<1];
     45         sum[v<<1|1] = (R - M) - sum[v<<1|1];
     46         flip[v] = 0;
     47     }
     48     if(light[v]){
     49         light[v<<1] ^= 1;
     50         light[v<<1|1] ^= 1;
     51         light[v] = 0;
     52     }
     53 }
     54 inline void pushup(int v){
     55     sum[v] = sum[v<<1] + sum[v<<1|1];
     56 }
     57 void update(bool OP,int L,int R,int lt,int rt,int v){
     58     if(lt <= L && rt >= R){
     59         if(OP){
     60             flip[v] ^= 1;
     61             sum[v] = (R - L + 1) - sum[v];
     62         }else light[v] ^= 1;
     63         return;
     64     }
     65     int mid = (L + R)>>1;
     66     pushdown(v,L,mid,R);
     67     if(lt <= mid) update(OP,L,mid,lt,rt,v<<1);
     68     if(rt > mid) update(OP,mid + 1,R,lt,rt,v<<1|1);
     69     pushup(v);
     70 }
     71 int query(bool OP,int L,int R,int lt,int rt,int v){
     72     if(lt <= L && rt >= R) return OP?sum[v]:light[v];
     73     int ret = 0,mid = (L + R)>>1;
     74     pushdown(v,L,mid,R);
     75     if(lt <= mid) ret = query(OP,L,mid,lt,rt,v<<1);
     76     if(rt > mid) ret += query(OP,mid+1,R,lt,rt,v<<1|1);
     77     return ret;
     78 }
     79 void modifyHeavy(int u,int v){
     80     while(top[u] != top[v]){
     81         if(dep[top[u]] < dep[top[v]]) swap(u,v);
     82         update(true,1,cnt,loc[top[u]],loc[u],1);
     83         u = fa[top[u]];
     84     }
     85     if(u == v) return;
     86     if(dep[u] > dep[v]) swap(u,v);
     87     update(true,1,cnt,loc[son[u]],loc[v],1);
     88 }
     89 void modifyLight(int u,int v){
     90     while(top[u] != top[v]){
     91         if(dep[top[u]] < dep[top[v]]) swap(u,v);
     92         update(false,1,cnt,loc[top[u]],loc[u],1);
     93         if(~son[u]) update(true,1,cnt,loc[son[u]],loc[son[u]],1);
     94         update(true,1,cnt,loc[top[u]],loc[top[u]],1);
     95         u = fa[top[u]];
     96     }
     97     if(dep[u] > dep[v]) swap(u,v);
     98     update(false,1,cnt,loc[u],loc[v],1);
     99     if(fa[u]) update(true,1,cnt,loc[u],loc[u],1);
    100     if(~son[v]) update(true,1,cnt,loc[son[v]],loc[son[v]],1);
    101 }
    102 int query(int u,int v,int ret = 0){
    103     while(top[u] != top[v]){
    104         if(dep[top[u]] < dep[top[v]]) swap(u,v);
    105         if(u != top[u]) ret += query(true,1,cnt,loc[son[top[u]]],loc[u],1);
    106         ret += query(true,1,cnt,loc[top[u]],loc[top[u]],1)^query(false,1,cnt,loc[fa[top[u]]],loc[fa[top[u]]],1);
    107         u = fa[top[u]];
    108     }
    109     if(u == v) return ret;
    110     if(dep[u] > dep[v]) swap(u,v);
    111     return ret + query(true,1,cnt,loc[son[u]],loc[v],1);
    112 }
    113 int main() {
    114     int kase,u,v,n,m,op;
    115     scanf("%d",&kase);
    116     while(kase--){
    117         memset(head,-1,sizeof head);
    118         memset(sum,0,sizeof sum);
    119         memset(flip,0,sizeof flip);
    120         memset(light,0,sizeof light);
    121         cnt = tot = 0;
    122         scanf("%d",&n);
    123         for(int i = 1; i < n; ++i){
    124             scanf("%d%d",&u,&v);
    125             add(u,v);
    126             add(v,u);
    127         }
    128         FindHeavyEdge(1,0,0);
    129         ConnectHeavyEdge(1,1);
    130         scanf("%d",&m);
    131         while(m--){
    132             scanf("%d%d%d",&op,&u,&v);
    133             switch(op){
    134                 case 1:modifyHeavy(u,v);break;
    135                 case 2:modifyLight(u,v);break;
    136                 case 3:printf("%d
    ",query(u,v));break;
    137                 default:;
    138             }
    139         }
    140     }
    141     return 0;
    142 }
    View Code
  • 相关阅读:
    selenium-元素无法定位解决办法
    OpenResty 最佳实践
    openresty 学习笔记小结:综合应用实例
    openresty 学习笔记六:使用session库
    openresty 学习笔记番外篇:python的一些扩展库
    openresty 学习笔记番外篇:python访问RabbitMQ消息队列
    openresty 学习笔记五:访问RabbitMQ消息队列
    openresty 学习笔记四:连接mysql和进行相关操作
    openresty 学习笔记三:连接redis和进行相关操作
    Grunt教程——初涉Grunt
  • 原文地址:https://www.cnblogs.com/crackpotisback/p/4900658.html
Copyright © 2020-2023  润新知