• bzoj4999 This Problem Is Too Simple!


    Description

    给您一颗树,每个节点有个初始值。
    现在支持以下两种操作:
    1. C i x(0<=x<2^31) 表示将i节点的值改为x。
    2. Q i j x(0<=x<2^31) 表示询问i节点到j节点的路径上有多少个值为x的节点。

    Input

    第一行有两个整数N,Q(1 ≤N≤ 100,000;1 ≤Q≤ 200,000),分别表示节点个数和操作个数。
    下面一行N个整数,表示初始时每个节点的初始值。
    接下来N-1行,每行两个整数x,y,表示x节点与y节点之间有边直接相连(描述一颗树)。
    接下来Q行,每行表示一个操作,操作的描述已经在题目描述中给出。

    Output

    对于每个Q输出单独一行表示所求的答案。

    Sample Input

    5 6
    10 20 30 40 50
    1 2
    1 3
    3 4
    3 5
    Q 2 3 40
    C 1 40
    Q 2 3 40
    Q 4 5 30
    C 3 10
    Q 4 5 30

    Sample Output

    0
    1
    1
    0

    正解:树链剖分+线段树。

    傻逼题,直接对于每一个权值建一棵线段树,然后树剖扣路径即可。

     1 #include <bits/stdc++.h>
     2 #define il inline
     3 #define RG register
     4 #define ll long long
     5 #define lb(x) (x & -x)
     6 #define N (300010)
     7 
     8 using namespace std;
     9 
    10 struct edge{ int nt,to; }g[N<<1];
    11 struct data{ int op,x,y,v; }q[N];
    12 
    13 int head[N],top[N],fa[N],son[N],dfn[N],dep[N],sz[N],n,num,cnt;
    14 int sum[20*N],ls[20*N],rs[20*N],rt[N],hsh[N],a[N],tot,Sz,Q;
    15 char ch[5];
    16 
    17 il int gi(){
    18   RG int x=0,q=1; RG char ch=getchar();
    19   while ((ch<'0' || ch>'9') && ch!='-') ch=getchar();
    20   if (ch=='-') q=-1,ch=getchar();
    21   while (ch>='0' && ch<='9') x=x*10+ch-48,ch=getchar();
    22   return q*x;
    23 }
    24 
    25 il void insert(RG int from,RG int to){
    26   g[++num]=(edge){head[from],to},head[from]=num; return;
    27 }
    28 
    29 il void dfs1(RG int x,RG int p){
    30   fa[x]=p,dep[x]=dep[p]+1,sz[x]=1; RG int v;
    31   for (RG int i=head[x];i;i=g[i].nt){
    32     v=g[i].to; if (v==p) continue;
    33     dfs1(v,x),sz[x]+=sz[v];
    34     if (sz[son[x]]<=sz[v]) son[x]=v;
    35   }
    36   return;
    37 }
    38 
    39 il void dfs2(RG int x,RG int p,RG int anc){
    40   top[x]=anc,dfn[x]=++cnt; RG int v;
    41   if (son[x]) dfs2(son[x],x,anc);
    42   for (RG int i=head[x];i;i=g[i].nt){
    43     v=g[i].to; if (v==p || v==son[x]) continue;
    44     dfs2(v,x,v);
    45   }
    46   return;
    47 }
    48 
    49 il void update(RG int &x,RG int l,RG int r,RG int p,RG int v){
    50   if (!x) x=++Sz; if (l==r){ sum[x]+=v; return; } RG int mid=(l+r)>>1;
    51   p<=mid ? update(ls[x],l,mid,p,v) : update(rs[x],mid+1,r,p,v);
    52   sum[x]=sum[ls[x]]+sum[rs[x]]; return;
    53 }
    54 
    55 il int query(RG int x,RG int l,RG int r,RG int xl,RG int xr){
    56   if (xl<=l && r<=xr) return sum[x]; RG int mid=(l+r)>>1;
    57   if (xr<=mid) return query(ls[x],l,mid,xl,xr);
    58   else if (xl>mid) return query(rs[x],mid+1,r,xl,xr);
    59   else return query(ls[x],l,mid,xl,mid)+query(rs[x],mid+1,r,mid+1,xr);
    60 }
    61 
    62 il int Query(RG int u,RG int v,RG int k){
    63   RG int ans=0;
    64   while (top[u]!=top[v]){
    65     if (dep[top[u]]<dep[top[v]]) swap(u,v);
    66     ans+=query(rt[k],1,n,dfn[top[u]],dfn[u]),u=fa[top[u]];
    67   }
    68   if (dep[u]>dep[v]) swap(u,v);
    69   ans+=query(rt[k],1,n,dfn[u],dfn[v]); return ans;
    70 }
    71 
    72 int main(){
    73 #ifndef ONLINE_JUDGE
    74   freopen("simple.in","r",stdin);
    75   freopen("simple.out","w",stdout);
    76 #endif
    77   n=gi(),Q=gi();
    78   for (RG int i=1;i<=n;++i) a[i]=gi(),hsh[++tot]=a[i];
    79   for (RG int i=1,x,y;i<n;++i) x=gi(),y=gi(),insert(x,y),insert(y,x);
    80   dfs1(1,0),dfs2(1,0,1);
    81   for (RG int i=1;i<=Q;++i){
    82     scanf("%s",ch);
    83     if (ch[0]=='C') q[i].op=1,q[i].x=gi(); else q[i].x=gi(),q[i].y=gi();
    84     q[i].v=gi(),hsh[++tot]=q[i].v;
    85   }
    86   sort(hsh+1,hsh+tot+1),tot=unique(hsh+1,hsh+tot+1)-hsh-1;
    87   for (RG int i=1;i<=n;++i) a[i]=lower_bound(hsh+1,hsh+tot+1,a[i])-hsh,update(rt[a[i]],1,n,dfn[i],1);
    88   for (RG int i=1;i<=Q;++i){
    89     q[i].v=lower_bound(hsh+1,hsh+tot+1,q[i].v)-hsh;
    90     if (q[i].op) update(rt[a[q[i].x]],1,n,dfn[q[i].x],-1),update(rt[a[q[i].x]=q[i].v],1,n,dfn[q[i].x],1);
    91     else printf("%d
    ",Query(q[i].x,q[i].y,q[i].v));
    92   }
    93   return 0;
    94 }
  • 相关阅读:
    做到就得到,人生成功的启示
    这个世界没什么过不去的事情,记我的经历
    要想富,先读书,没有文化要吃一辈子的亏
    git学习笔记11-git多人协作-实际多人怎么开发
    git学习笔记10-新开发的功能不想要了-强行删除分支
    git学习笔记09-bug分支-自己的分支改到一半了-要去改bug怎么办?
    git学习笔记08-分支管理策略-实际上我们应该怎么应用分支
    git学习笔记07-冲突了怎么办-那就解决冲突呗
    git学习笔记06-创建分支合并分支-比svn快多了,因为只有指针在改变
    git学习笔记05-从远程库克隆
  • 原文地址:https://www.cnblogs.com/wfj2048/p/7603539.html
Copyright © 2020-2023  润新知