zoukankan      html  css  js  c++  java
  • 【BZOJ3531】【SDOI2014】旅行

    题目传送门

    题目大意:给定一棵无根树,每个节点有自己的类别和权值,现在给定两个类别相同的点,叫你求这2点路径上同类别节点的权值和/最大权值。

    节点类别与权值会改变。

    解题思路:考虑对每一个类别开一棵线段树,动态开点,可以写指针,也可以开数组写链表,然后剩下的就是树剖的东西了。我写的是指针,跑的略慢一些,时间效率为( O(q log^{2} n) ).

    代码由于是在自家的mac上码的,所以和以前风格不大一样。

      1 #include <stdio.h>
      2 #define MN 100005
      3 inline void swp(int &a,int &b){a ^= b ^= a ^= b;}
      4 inline int max(int a,int b){return a > b ? a : b;}
      5 inline int in(){
      6     int x = 0 ,f = 1; char ch = getchar();
      7     while (ch < '0' || ch > '9') f = ch=='-' ? -1 :1 , ch = getchar();
      8     while (ch >= '0' && ch <= '9' ) x = (x<<3) + (x<<1) + ch - '0',ch = getchar();
      9     return x*f;
     10 }
     11 struct segment_tree{
     12     segment_tree *ls , *rs;
     13     int sum,ma;
     14     void combine(){
     15         sum = ma = 0;
     16         if (ls != NULL){
     17             sum += ls -> sum;
     18             ma = max( ma , ls -> ma );
     19         }if (rs != NULL){
     20             sum += rs -> sum;
     21             ma = max( ma , rs -> ma );
     22         }
     23     }
     24     segment_tree (int sum=0,int ma=0):sum(sum),ma(ma){ls = rs = NULL;}
     25 }*ST[MN];
     26 #define S_T segment_tree
     27 int to[MN<<1],nxt[MN<<1],cnt,head[MN];
     28 int n,q,top[MN],siz[MN],son[MN],val[MN],belief[MN],fa[MN],dep[MN],pos[MN],dfsn;
     29 inline void ins(int x,int y){to[++cnt] = y , nxt[cnt] = head[x] , head[x] = cnt;}
     30 inline void insw(int x,int y){ins(x,y); ins(y,x);}
     31 inline void dfs1(int u,int f,int d){
     32     siz[u] = 1; dep[u] = d; fa[u] = f;
     33     for (register int i = head[u]; i; i = nxt[i])
     34         if (to[i] != f) {
     35             dfs1(to[i],u,d+1); siz[u] += siz[to[i]];
     36             if (siz[son[u]] < siz[to[i]]) son[u] = to[i];
     37         }
     38 }
     39 inline void dfs2(int u,int tp){
     40     top[u] = tp; pos[u] = (++dfsn); if (son[u]) dfs2(son[u],tp);
     41     for (register int i = head[u]; i; i = nxt[i])
     42         if (to[i] != fa[u] && to[i] != son[u]) dfs2(to[i],to[i]);
     43 }
     44 #define mid (l+r>>1)
     45 inline void insert(S_T* &x,int l,int r,int pos,int val){
     46     if (x == NULL) x = new S_T;
     47     if (l == r){x -> sum = x -> ma = val; return;}
     48     if (pos <= mid) insert(x -> ls,l,mid,pos,val);
     49     else insert(x -> rs,mid+1,r,pos,val);x->combine();
     50 }
     51 inline void Delete(S_T* &x,int l,int r,int pos){
     52     if (l==r){delete x; x = NULL; return; }
     53     if (pos<=mid) Delete(x -> ls,l,mid,pos);
     54     else Delete(x -> rs,mid+1,r,pos);
     55     if (x -> ls == NULL && x -> rs == NULL){delete x; x = NULL; return; }
     56     else x -> combine();
     57 }
     58 inline int QM(S_T* &x,int l,int r,int a,int b){
     59     if (x == NULL) return 0;
     60     if (l == a && r == b) return x -> ma;
     61     if (b<=mid) return QM(x -> ls,l,mid,a,b);
     62     if (a>mid) return QM(x -> rs,mid+1,r,a,b);
     63     return max(QM(x -> ls,l,mid,a,mid),QM(x -> rs,mid+1,r,mid+1,b));
     64 }
     65 inline int QS(S_T* &x,int l,int r,int a,int b){
     66     if (x == NULL) return 0;
     67     if (l == a && r == b) return x -> sum;
     68     if (b<=mid) return QS(x -> ls,l,mid,a,b);
     69     if (a>mid) return QS(x -> rs,mid+1,r,a,b);
     70     return QS(x -> ls,l,mid,a,mid)+QS(x -> rs,mid+1,r,mid+1,b);
     71 }
     72 inline int qm(int belief,int x,int y){
     73     register int res = 0;
     74     while (top[x] != top[y]){
     75         if (dep[top[x]] < dep[top[y]]) swp(x,y);
     76         res = max(res,QM(ST[belief],1,n,pos[top[x]],pos[x]));
     77         x = fa[top[x]];
     78     }if (dep[x] > dep[y]) swp(x,y);res = max(res,QM(ST[belief],1,n,pos[x],pos[y]));
     79     return res;
     80 }
     81 inline int qs(int belief,int x,int y){
     82     register int res = 0;
     83     while (top[x] != top[y]){
     84         if (dep[top[x]] < dep[top[y]]) swp(x,y);
     85         res += QS(ST[belief],1,n,pos[top[x]],pos[x]);
     86         x = fa[top[x]];
     87     }if (dep[x] > dep[y]) swp(x,y);res += QS(ST[belief],1,n,pos[x],pos[y]);
     88     return res;
     89 }
     90 void init(){
     91     n = in() , q = in();
     92     for (int i = 1; i <= n; ++i) val[i] = in() , belief[i] = in();
     93     for (register int i = 1; i < n; ++i) insw(in(),in());
     94     dfs1(1,1,1);dfs2(1,1);
     95     for (register int i = 1; i <= n; ++i)
     96         insert(ST[belief[i]],1,n,pos[i],val[i]);
     97 }
     98 void solve(){
     99     while(q--){
    100         register char op[5]; scanf("%s",op);
    101         register int x=in(),y=in();
    102         if (op[0] == 'C'){
    103             if (op[1] == 'C'){
    104                 Delete(ST[belief[x]],1,n,pos[x]);
    105                 insert(ST[belief[x] = y],1,n,pos[x],val[x]);
    106             }else insert(ST[belief[x]],1,n,pos[x],val[x]=y);
    107         }else{
    108             if (op[1] == 'M') printf("%d
    ",qm(belief[x],x,y));
    109             else printf("%d
    ",qs(belief[x],x,y));
    110         }
    111     }
    112 }
    113 int main(){ init(); solve();}
  • 相关阅读:
    JUnit入门
    Spring+Ibatis集成开发实例
    如花搞笑图片集锦(转贴)
    Jmeter接口測试
    java 解析国密SM2算法证书
    [BZOJ2324][ZJOI2011][最小费用最大流]营救皮卡丘
    定制ToolChain for ARM
    几种更新(Update语句)查询的方法
    linux杂谈(十七):iscsi存储分离技术
    17点50分系列-如何能让你的技术掌握的更深入?
  • 原文地址:https://www.cnblogs.com/Melacau/p/BZOJ3531.html
Copyright © 2011-2022 走看看