zoukankan      html  css  js  c++  java
  • bzoj 4999 This Problem Is Too Simple!

    题目大意:

    给一颗树,每个节点有个初始值

    现在支持以下两种操作:

    1. C i x 表示将i节点的值改为x

    2. Q i j x 表示询问i节点到j节点的路径上有多少个值为x的节点

    思路:

    首先可以想到树链剖分

    虽然颜色的数量看起来很吓人

    但是实际上只可能有n+q种颜色

    所以我们的线段树只需要像主席树那样去写就可以了

      1 #include<iostream>
      2 #include<cstdio>
      3 #include<cmath>
      4 #include<cstdlib>
      5 #include<cstring>
      6 #include<algorithm>
      7 #include<vector>
      8 #include<queue>
      9 #include<map>
     10 #define inf 2139062143
     11 #define ll long long
     12 #define MAXN 100100
     13 using namespace std;
     14 inline int read()
     15 {
     16     int x=0,f=1;char ch=getchar();
     17     while(!isdigit(ch)) {if(ch=='-') f=-1;ch=getchar();}
     18     while(isdigit(ch)) {x=x*10+ch-'0';ch=getchar();}
     19     return x*f;
     20 }
     21 int n,T,val[MAXN],to[MAXN<<1],fst[MAXN],nxt[MAXN<<1],Cnt,cnt[MAXN],dep[MAXN],fa[MAXN],bl[MAXN],hsh[MAXN],rt[MAXN<<2],clr;
     22 map <int,int> m;
     23 struct data {int ls,rs,sum;}tr[MAXN<<7];
     24 void add(int u,int v) {nxt[++Cnt]=fst[u],fst[u]=Cnt,to[Cnt]=v;}
     25 void dfs(int x)
     26 {
     27     cnt[x]=1;
     28     for(int i=fst[x];i;i=nxt[i])
     29     {
     30         if(to[i]==fa[x]) continue;
     31         fa[to[i]]=x,dep[to[i]]=dep[x]+1;
     32         dfs(to[i]);
     33         cnt[x]+=cnt[to[i]];
     34     }
     35 }
     36 void Dfs(int x,int anc)
     37 {
     38     int hvs=0;hsh[x]=++Cnt,bl[x]=anc;
     39     for(int i=fst[x];i;i=nxt[i])
     40         if(to[i]!=fa[x]&&cnt[hvs]<cnt[to[i]]) hvs=to[i];
     41     if(!hvs) return ;
     42     Dfs(hvs,anc);
     43     for(int i=fst[x];i;i=nxt[i])
     44         if(to[i]!=fa[x]&&to[i]!=hvs) Dfs(to[i],to[i]);
     45 }
     46 void inst(int &k,int l,int r,int x,int w)
     47 {
     48     if(!k) k=++Cnt;
     49     tr[k].sum+=w;
     50     if(l==r) return;
     51     int mid=(l+r)>>1;
     52     if(x<=mid) inst(tr[k].ls,l,mid,x,w);
     53     else inst(tr[k].rs,mid+1,r,x,w);
     54 }
     55 int query(int k,int l,int r,int a,int b)
     56 {
     57     if(!k) return 0;
     58     if(a==l&&r==b) return tr[k].sum;
     59     int mid=(l+r)>>1;
     60     if(b<=mid) return query(tr[k].ls,l,mid,a,b);
     61     else if(a>mid) return query(tr[k].rs,mid+1,r,a,b);
     62     else return query(tr[k].ls,l,mid,a,mid)+query(tr[k].rs,mid+1,r,mid+1,b);
     63 }
     64 int main()
     65 {
     66     n=read(),T=read();int a,b,c,res;char ch[5];
     67     for(int i=1;i<=n;i++) val[i]=read();
     68     for(int i=1;i<n;i++) {a=read(),b=read();add(a,b);add(b,a);}
     69     dep[1]=1;
     70     dfs(1);Cnt=0;
     71     Dfs(1,1);Cnt=0;
     72     for(int i=1;i<=n;i++) 
     73     {
     74         if(!m[val[i]]) m[val[i]]=++clr;
     75         inst(rt[m[val[i]]],1,n,hsh[i],1);
     76     }
     77     while(T--)
     78     {
     79         scanf("%s",ch);a=read(),b=read();
     80         if(ch[0]=='C')
     81         {
     82             inst(rt[m[val[a]]],1,n,hsh[a],-1);
     83             if(!m[b]) m[b]=++clr;
     84             inst(rt[m[b]],1,n,hsh[a],1);
     85             val[a]=b;
     86         }
     87         else
     88         {
     89             c=read(),res=0;
     90             if(!m[c]) {puts("0");continue;}
     91             while(bl[a]!=bl[b])
     92             {
     93                 //cout<<a<<" "<<b<<" "<<res<<endl;
     94                 if(dep[bl[a]]<dep[bl[b]]) swap(a,b);
     95                 res+=query(rt[m[c]],1,n,hsh[bl[a]],hsh[a]);
     96                 a=fa[bl[a]];
     97             }
     98         //cout<<a<<" "<<b<<" "<<res<<endl;
     99             res+=query(rt[m[c]],1,n,min(hsh[a],hsh[b]),max(hsh[a],hsh[b]));
    100             printf("%d
    ",res);
    101         }
    102     }
    103 }
    View Code
  • 相关阅读:
    Clojure编写一个阶乘程序 使用递归
    SSH框架学习步骤
    js需要清楚的内存模型
    SeaJS结合javascript面向对象使用笔记(一)
    函数副作用
    linux笔记2
    C#事件与接口编程实例
    C#的接口基础教程之七 覆盖虚接口
    C#的接口基础教程之六 接口转换
    C#的接口基础教程之五 实现接口
  • 原文地址:https://www.cnblogs.com/yyc-jack-0920/p/8468788.html
Copyright © 2011-2022 走看看