zoukankan      html  css  js  c++  java
  • BZOJ 4372 烁烁的游戏

    Description

    背景:烁烁很喜欢爬树,这吓坏了树上的皮皮鼠。
    题意:
    给定一颗n个节点的树,边权均为1,初始树上没有皮皮鼠。
    烁烁他每次会跳到一个节点u,把周围与他距离不超过d的节点各吸引出w只皮皮鼠。皮皮鼠会被烁烁吸引,所以会一直待在节点上不动。
    烁烁很好奇,在当前时刻,节点u有多少个他的好朋友---皮皮鼠。
    大意:
    给一颗n个节点的树,边权均为1,初始点权均为0,m次操作:
    Q x:询问x的点权。
    M x d w:将树上与节点x距离不超过d的节点的点权均加上w。

    Input

    第一行两个正整数:n,m
    接下来的n-1行,每行三个正整数u,v,代表u,v之间有一条边。
    接下来的m行,每行给出上述两种操作中的一种。

    Output

    对于每个Q操作,输出当前x节点的皮皮鼠数量。

    Sample Input

    7 6
    1 2
    1 4
    1 5
    2 3
    2 7
    5 6
    M 1 1 2
    Q 5
    M 2 2 3
    Q 3
    M 1 2 1
    Q 2

    Sample Output

    2
    3
    6
    和震波哪题很像,也是线段树+动态点分治
    只不过将操作换了,一样的原理
      1 #include<iostream>
      2 #include<cstdio>
      3 #include<cstring>
      4 #include<algorithm>
      5 #include<cmath>
      6 using namespace std;
      7 #define MAX 120000
      8 struct Node
      9 {
     10   int next,to;
     11 }edge[MAX<<1];
     12 int num,head[MAX];
     13 int dep[MAX],fa[MAX],pos,size[MAX],minsize,root;
     14 int FA[MAX],son[MAX],top[MAX],Size;
     15 int lazy[MAX*150];
     16 int ch[MAX*150][2],RT[MAX<<1],n,m;
     17 int ans,val[MAX];
     18 bool vis[MAX];
     19 inline int gi()
     20 {
     21   int x=0,flag=1;
     22   char ch=getchar();
     23   while (ch<'0'||ch>'9')
     24     {
     25       if (ch=='-') flag=-1;
     26       ch=getchar();
     27     }
     28   while (ch>='0'&&ch<='9')
     29     {
     30       x=(x<<3)+(x<<1)+ch-'0';
     31       ch=getchar();
     32     }
     33   return x*flag;
     34 }
     35 inline void add(int u,int v)
     36 {
     37   num++;
     38   edge[num].next=head[u];
     39   head[u]=num;
     40   edge[num].to=v;
     41 }
     42 void dfs1(int x,int pa)
     43 {
     44   size[x]=1;
     45   dep[x]=dep[pa]+1;
     46   for (int i=head[x];i;i=edge[i].next)
     47     {
     48       int v=edge[i].to;
     49       if (v==pa) continue;
     50       fa[v]=x;
     51       dfs1(v,x);
     52       size[x]+=size[v];
     53       if (size[son[x]]<size[v])
     54       son[x]=v;
     55     }
     56 }
     57 void dfs2(int x,int tp)
     58 {
     59   top[x]=tp;
     60   if (son[x])
     61     dfs2(son[x],tp);
     62   for (int i=head[x];i;i=edge[i].next)
     63     {
     64       int v=edge[i].to;
     65       if (v==fa[x]||v==son[x]) continue;
     66       dfs2(v,v);
     67     }
     68 }
     69 int lca(int x,int y)
     70 {
     71   while (top[x]!=top[y])
     72     {
     73       if (dep[top[x]]<dep[top[y]]) swap(x,y);
     74       x=fa[top[x]];    
     75     }
     76   if (dep[x]<dep[y]) return x;
     77   return y;
     78 }
     79 int dis(int x,int y)
     80 {
     81   return dep[x]+dep[y]-(dep[lca(x,y)]<<1);
     82 }
     83 void get_root(int x,int pa)
     84 {
     85   size[x]=1;
     86   int ret=0;
     87   for (int i=head[x];i;i=edge[i].next)
     88     {
     89       int v=edge[i].to;
     90       if (v==pa||vis[v]) continue;
     91       get_root(v,x);
     92       size[x]+=size[v];
     93       if (size[v]>ret) ret=size[v];
     94     }
     95   if (Size-size[x]>ret) ret=Size-size[x];
     96   if (ret<minsize) minsize=ret,root=x;
     97 }
     98 void solve(int x,int pa)
     99 {
    100   vis[x]=1;
    101   FA[x]=pa;
    102   for (int i=head[x];i;i=edge[i].next)
    103     {
    104       int v=edge[i].to;
    105       if (vis[v]) continue;
    106       minsize=n;Size=size[v];
    107       get_root(v,x);
    108       solve(root,x);
    109     }
    110 }
    111 void update(int &rt,int l,int r,int L,int R,int w)
    112 {
    113   if (!rt) rt=++pos;
    114   if (l>=L&&r<=R)
    115   {lazy[rt]+=w;return;}
    116   int mid=(l+r)>>1;
    117   if (L<=mid) update(ch[rt][0],l,mid,L,R,w);
    118   if (R>mid) update(ch[rt][1],mid+1,r,L,R,w);
    119 }
    120 int query(int rt,int l,int r,int x)
    121 {
    122   if (!rt) return 0;
    123   if (l==r)
    124     return lazy[rt];
    125   int mid=(l+r)>>1;
    126   if (x<=mid) return query(ch[rt][0],l,mid,x)+lazy[rt];
    127   else return query(ch[rt][1],mid+1,r,x)+lazy[rt];
    128 }
    129 void change(int u,int k,int w)
    130 {
    131   update(RT[u],0,n,0,k,w);
    132   for (int i=u;FA[i];i=FA[i])
    133     {
    134       int d=dis(u,FA[i]);
    135       if (d>k) continue;
    136       update(RT[FA[i]],0,n,0,k-d,w);
    137       update(RT[i+n],0,n,0,k-d,w);
    138     }
    139 }
    140 void ask(int u)
    141 {
    142   ans+=query(RT[u],0,n,0);
    143   for (int i=u;FA[i];i=FA[i])
    144     {
    145       int d=dis(u,FA[i]);
    146       ans+=query(RT[FA[i]],0,n,d);
    147       ans-=query(RT[i+n],0,n,d);
    148     }
    149 }
    150 int main()
    151 {int u,v;
    152 char s[10];
    153   cin>>n>>m;
    154   for (int i=1;i<=n-1;i++)
    155     {
    156       u=gi();v=gi();
    157       add(u,v);add(v,u);
    158     }
    159   dfs1(1,0);
    160   dfs2(1,1);
    161   minsize=Size=n;
    162   get_root(1,0);
    163   solve(root,0);
    164   ans=0;
    165   for (int i=1;i<=m;i++)
    166     {
    167       scanf("%s",s); 
    168       if (s[0]=='Q')
    169         {
    170             ans=0;
    171             int x=gi();
    172             ask(x);
    173             printf("%d
    ",ans);
    174         }
    175       else
    176         {
    177             int u=gi(),k=gi(),w=gi();
    178             change(u,k,w);
    179         }
    180     }
    181   return 0;
    182 }
    183 
  • 相关阅读:
    计算机专业及软件开发推荐书籍
    摘抄Interrupt Architecture in Microsoft Windows CE .NET
    摘抄Multithreaded Programming on the Pocket PC with Visual C++
    摘抄Driver Code Structure
    摘抄Multimedia Streaming on Microsoft Windows CE 3.0
    摘抄Creating a Board Support Package Using the Windows CE .NET CEC Editor
    摘抄 Board Support Package, Boot Loader, and Kernel Startup Sequence
    摘抄The Case of the Missing Ordinal
    摘录Windows CE API机制初探
    摘抄非技术追梦—SQUARE大传
  • 原文地址:https://www.cnblogs.com/Y-E-T-I/p/8366368.html
Copyright © 2011-2022 走看看