zoukankan      html  css  js  c++  java
  • BZOJ 3531 SDOI2014 旅行 树链剖分+线段树动态开点

    题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=3531

    题意概述:
      给出一棵N个点的树,树上的每个结点有一个颜色和权值,支持以下四种操作:
      1.将点x的颜色改成c。
      2.将点x的权值给成w。
      3.询问x->y路径上和端点相同颜色的点的权值总和(端点颜色相同)。
      4.询问x->y路径上和端点相同颜色的点的权值最大值(端点颜色相同)。

    分析:

      首先树链剖分,每条链开C棵维护每个颜色的线段树。动态开点。

      感觉没什么好说的......考试的时候灵光一闪就来了......之前还在YYlct之类的......

      1 #include<iostream>
      2 #include<cstdio>
      3 #include<cstring>
      4 #include<cstdlib>
      5 #include<algorithm>
      6 #include<cmath>
      7 #include<queue>
      8 #include<set>
      9 #include<map>
     10 #include<vector>
     11 #include<cctype>
     12 using namespace std;
     13 const int maxn=100005;
     14 const int SIZE=4000005;
     15 
     16 int N,Q,C[maxn],W[maxn];
     17 map<int,int>rt[maxn];
     18 struct edge{ int to,next; }E[maxn<<1];
     19 int first[maxn],np,dep[maxn],top[maxn],fa[maxn],son[maxn],sz[maxn],len[maxn];
     20 int lc[SIZE],rc[SIZE],sum[SIZE],mx[SIZE],np2;
     21 
     22 void _scanf(int &x)
     23 {
     24     x=0;
     25     char ch=getchar();
     26     while(ch<'0'||ch>'9') ch=getchar();
     27     while(ch>='0'&&ch<='9') x=x*10+ch-'0',ch=getchar();
     28 }
     29 void _scanf(char *s)
     30 {
     31     int cnt=0;
     32     char ch=getchar();
     33     while(!isalpha(ch)) ch=getchar();
     34     while(isalpha(ch)) s[cnt++]=ch,ch=getchar();
     35     s[cnt]='';
     36 }
     37 int out_cnt,out[15];
     38 void _printf(int x)
     39 {
     40     out[++out_cnt]=x%10,x/=10;
     41     while(x) out[++out_cnt]=x%10,x/=10;
     42     while(out_cnt) putchar('0'+out[out_cnt--]);
     43     putchar('
    ');
     44 }
     45 void add_edge(int u,int v){
     46     E[++np]=(edge){v,first[u]};
     47     first[u]=np;
     48 }
     49 void data_in()
     50 {
     51     _scanf(N);_scanf(Q);
     52     for(int i=1;i<=N;i++) _scanf(W[i]),_scanf(C[i]);
     53     int x,y;
     54     for(int i=1;i<N;i++){
     55         _scanf(x);_scanf(y);
     56         add_edge(x,y); add_edge(y,x);
     57     }
     58 }
     59 void DFS1(int i,int f,int d){
     60     fa[i]=f,dep[i]=d,sz[i]=1;
     61     for(int p=first[i];p;p=E[p].next){
     62         int j=E[p].to;
     63         if(j==f) continue;
     64         DFS1(j,i,d+1);
     65         sz[i]+=sz[j];
     66         if(sz[j]>sz[son[i]]) son[i]=j;
     67     }
     68 }
     69 void DFS2(int i,int f,int tp){
     70     top[i]=tp,len[tp]++;
     71     if(son[i]) DFS2(son[i],i,tp);
     72     for(int p=first[i];p;p=E[p].next){
     73         int j=E[p].to;
     74         if(j==f||j==son[i]) continue;
     75         DFS2(j,i,j);
     76     }
     77 }
     78 int newnode(){
     79     np2++,lc[np2]=rc[np2]=0,sum[np2]=mx[np2]=0;
     80     return np2;
     81 }
     82 void pushup(int now){
     83     mx[now]=max(mx[lc[now]],mx[rc[now]]);
     84     sum[now]=sum[lc[now]]+sum[rc[now]];
     85 }
     86 void update(int &now,int L,int R,int pos,int v){
     87     if(!now) now=newnode();
     88     if(L==R){ sum[now]=mx[now]=v; return; }
     89     int m=L+R>>1;
     90     if(pos<=m) update(lc[now],L,m,pos,v);
     91     else update(rc[now],m+1,R,pos,v);
     92     pushup(now);
     93 }
     94 void build(int i,int f){
     95     update(rt[top[i]][C[i]],0,len[top[i]]-1,dep[i]-dep[top[i]],W[i]);
     96     for(int p=first[i];p;p=E[p].next){
     97         if(E[p].to==f) continue;
     98         build(E[p].to,i);
     99     }
    100 }
    101 int query1(int now,int L,int R,int A,int B){
    102     if(!now) return 0;
    103     if(A<=L&&R<=B) return sum[now];
    104     int m=L+R>>1;
    105     if(B<=m) return query1(lc[now],L,m,A,B);
    106     if(A>m) return query1(rc[now],m+1,R,A,B);
    107     return query1(lc[now],L,m,A,B)+query1(rc[now],m+1,R,A,B);
    108 }
    109 int query2(int now,int L,int R,int A,int B){
    110     if(!now) return 0;
    111     if(A<=L&&R<=B) return mx[now];
    112     int m=L+R>>1;
    113     if(B<=m) return query2(lc[now],L,m,A,B);
    114     if(A>m) return query2(rc[now],m+1,R,A,B);
    115     return max(query2(lc[now],L,m,A,B),query2(rc[now],m+1,R,A,B));
    116 }
    117 int LCA(int x,int y){
    118     while(top[x]!=top[y]){
    119         if(dep[top[x]]<dep[top[y]]) swap(x,y);
    120         x=fa[top[x]];
    121     }
    122     return dep[x]<dep[y]?x:y;
    123 }
    124 int query_s(int x,int y,int c){
    125     int re=0;
    126     while(top[x]!=top[y]){
    127         re+=query1(rt[top[x]][c],0,len[top[x]]-1,0,dep[x]-dep[top[x]]);
    128         x=fa[top[x]];
    129     }
    130     re+=query1(rt[top[x]][c],0,len[top[x]]-1,dep[y]-dep[top[x]],dep[x]-dep[top[x]]);
    131     return re;
    132 }
    133 int query_m(int x,int y,int c){
    134     int re=0;
    135     while(top[x]!=top[y]){
    136         re=max(re,query2(rt[top[x]][c],0,len[top[x]]-1,0,dep[x]-dep[top[x]]));
    137         x=fa[top[x]];
    138     }
    139     re=max(re,query2(rt[top[x]][c],0,len[top[x]]-1,dep[y]-dep[top[x]],dep[x]-dep[top[x]]));
    140     return re;
    141 }
    142 void work()
    143 {
    144     DFS1(1,0,1);
    145     DFS2(1,0,1);
    146     build(1,0);
    147     char op[5];
    148     int x,y,z,p,c,w,ans;
    149     for(int i=1;i<=Q;i++){
    150         _scanf(op);
    151         if(op[0]=='C'&&op[1]=='C'){
    152             _scanf(x);_scanf(c);
    153             update(rt[top[x]][C[x]],0,len[top[x]]-1,dep[x]-dep[top[x]],0);
    154             update(rt[top[x]][C[x]=c],0,len[top[x]]-1,dep[x]-dep[top[x]],W[x]);
    155         }
    156         else if(op[0]=='C'&&op[1]=='W'){
    157             _scanf(x);_scanf(w);
    158             update(rt[top[x]][C[x]],0,len[top[x]]-1,dep[x]-dep[top[x]],W[x]=w);
    159         }
    160         else if(op[1]=='S'){
    161             _scanf(x);_scanf(y);
    162             z=LCA(x,y);
    163             _printf(query_s(x,z,C[x])+query_s(y,z,C[x])-(C[z]==C[x]?W[z]:0));
    164         }
    165         else if(op[1]=='M'){
    166             _scanf(x);_scanf(y);
    167             z=LCA(x,y);
    168             _printf(max(query_m(x,z,C[x]),query_m(y,z,C[x])));
    169         }
    170     }
    171 }
    172 int main()
    173 {
    174     data_in();
    175     work();
    176     return 0;
    177 }
    View Code
     
  • 相关阅读:
    mysqldump 导出数据库为DBname的表名为Tname的表结构 导出数据库的所有表的表结构
    mysqldump 备份某张表 Warning: A partial dump from a server that has GTIDs will by default include the GTIDs of all transactions,
    nfs missing codepage or helper program, or other error
    date 增加一个小时 减少一个小时
    mysqldump 备份单个数据库
    mysql删除账户
    怎么删除某个用户的所有帖子?
    mongodb删除重复数据
    ReSharper2018破解详细方法
    激活windows和office
  • 原文地址:https://www.cnblogs.com/KKKorange/p/8644896.html
Copyright © 2011-2022 走看看