• BZOJ4372: 烁烁的游戏(动态点分治)


    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<cstdio>
      2 #include<cstring>
      3 #include<algorithm>
      4 const int N=100010;
      5 struct pnt{
      6     int hd;
      7     int fa;
      8     int f;
      9     int tp;
     10     int wgt;
     11     int mxs;
     12     int dis;
     13     bool vis;
     14     int roota;
     15     int rootp;
     16 }p[N];
     17 struct trnt{
     18     int ls;
     19     int rs;
     20     int val;
     21 }tr[40000000];
     22 struct ent{
     23     int twd;
     24     int lst;
     25 }e[N<<1];
     26 int n,m;
     27 int cnt;
     28 int siz;
     29 int root;
     30 int size;
     31 int maxsize;
     32 char cmd[1000];
     33 void ade(int f,int t)
     34 {
     35     cnt++;
     36     e[cnt].twd=t;
     37     e[cnt].lst=p[f].hd;
     38     p[f].hd=cnt;
     39     return ;
     40 }
     41 void Basic_dfs(int x,int f)
     42 {
     43     p[x].dis=p[f].dis+1;
     44     p[x].f=f;
     45     p[x].wgt=1;
     46     int maxs=-1;
     47     for(int i=p[x].hd;i;i=e[i].lst)
     48     {
     49         int to=e[i].twd;
     50         if(to==f)
     51             continue;
     52         Basic_dfs(to,x);
     53         p[x].wgt+=p[to].wgt;
     54         if(maxs<p[to].wgt)
     55         {
     56             maxs=p[to].wgt;
     57             p[x].mxs=to;
     58         }
     59     }
     60     return ;
     61 }
     62 void Build_dfs(int x,int top)
     63 {
     64     if(!x)
     65         return ;
     66     p[x].tp=top;
     67     Build_dfs(p[x].mxs,top);
     68     for(int i=p[x].hd;i;i=e[i].lst)
     69     {
     70         int to=e[i].twd;
     71         if(to==p[x].mxs||to==p[x].f)
     72             continue;
     73         Build_dfs(to,to);
     74     }
     75     return ;
     76 }
     77 int Lca(int x,int y)
     78 {
     79     while(p[x].tp!=p[y].tp)
     80     {
     81         if(p[p[x].tp].dis<p[p[y].tp].dis)
     82             std::swap(x,y);
     83         x=p[p[x].tp].f;
     84     }
     85     if(p[x].dis>p[y].dis)
     86         std::swap(x,y);
     87     return x;
     88 }
     89 int Dis(int x,int y)
     90 {
     91     int z=Lca(x,y);
     92     return p[x].dis+p[y].dis-2*p[z].dis;
     93 }
     94 void grc_dfs(int x,int f)
     95 {
     96     p[x].wgt=1;
     97     int maxs=-1;
     98     for(int i=p[x].hd;i;i=e[i].lst)
     99     {
    100         int to=e[i].twd;
    101         if(to==f||p[to].vis)
    102             continue;
    103         grc_dfs(to,x);
    104         p[x].wgt+=p[to].wgt;
    105         if(maxs<p[to].wgt)
    106             maxs=p[to].wgt;
    107     }
    108     maxs=std::max(maxs,size-p[x].wgt);
    109     if(maxs<maxsize)
    110     {
    111         root=x;
    112         maxsize=maxs;
    113     }
    114     return ;
    115 }
    116 void bin_dfs(int x,int f)
    117 {
    118     p[x].fa=f;
    119     p[x].vis=true;
    120     int tmp=size;
    121     for(int i=p[x].hd;i;i=e[i].lst)
    122     {
    123         int to=e[i].twd;
    124         if(p[to].vis)
    125             continue;
    126         root=0;
    127         if(p[x].wgt>p[to].wgt)
    128             size=p[to].wgt;
    129         else
    130             size=tmp-p[x].wgt;
    131         maxsize=0x3f3f3f3f;
    132         grc_dfs(to,to);
    133         bin_dfs(root,x);
    134     }
    135     return ;
    136 }
    137 void update(int &spc,int l,int r,int ll,int rr,int v)
    138 {
    139     if(ll>r||l>rr)
    140         return ;
    141     if(!spc)
    142         spc=++siz;
    143     if(ll<=l&&r<=rr)
    144     {
    145         tr[spc].val+=v;
    146         return ;
    147     }
    148     int mid=(l+r)>>1;
    149     update(tr[spc].ls,l,mid,ll,rr,v);
    150     update(tr[spc].rs,mid+1,r,ll,rr,v);
    151     return ;
    152 }
    153 int query(int spc,int l,int r,int pos)
    154 {
    155     if(!spc)
    156         return 0;
    157     int ans=tr[spc].val;
    158     if(l==r)
    159         return ans;
    160     int mid=(l+r)>>1;
    161     if(pos<=mid)
    162         ans+=query(tr[spc].ls,l,mid,pos);
    163     else
    164         ans+=query(tr[spc].rs,mid+1,r,pos);
    165     return ans;
    166 }
    167 void Update(int x,int k,int val)
    168 {
    169     update(p[x].rootp,0,n-1,0,k,val);
    170     for(int i=x;p[i].fa;i=p[i].fa)
    171     {
    172         int d=Dis(x,p[i].fa);
    173         if(k<d)
    174             continue;
    175         update(p[p[i].fa].rootp,0,n-1,0,k-d,val);
    176         update(p[i].roota,0,n-1,0,k-d,val);
    177     }
    178     return ;
    179 }
    180 int Query(int x)
    181 {
    182     int ans=query(p[x].rootp,0,n-1,0);
    183     for(int i=x;p[i].fa;i=p[i].fa)
    184     {
    185         int d=Dis(x,p[i].fa);
    186         ans+=query(p[p[i].fa].rootp,0,n-1,d)-query(p[i].roota,0,n-1,d);
    187     }
    188     return ans;
    189 }
    190 int main()
    191 {
    192     scanf("%d%d",&n,&m);
    193     for(int i=1;i<n;i++)
    194     {
    195         int a,b;
    196         scanf("%d%d",&a,&b);
    197         ade(a,b);
    198         ade(b,a);
    199     }
    200     Basic_dfs(1,1);
    201     Build_dfs(1,1);
    202     root=0;
    203     size=n;
    204     maxsize=0x3f3f3f3f;
    205     grc_dfs(1,1);
    206     bin_dfs(root,0);
    207     while(m--)
    208     {
    209         scanf("%s",cmd+1);
    210         if(cmd[1]=='M')
    211         {
    212             int x,k,v;
    213             scanf("%d%d%d",&x,&k,&v);
    214             Update(x,k,v);
    215         }else{
    216             int x;
    217             scanf("%d",&x);
    218             printf("%d
    ",Query(x));
    219         }
    220     }
    221     return 0;
    222 }
  • 相关阅读:
    设计模式学习--------8.抽象工厂模式学习
    设计模式学习--------7.工厂方法模式学习
    算法学习---对象类型的数组二分查找实现
    算法学习---基本数据类型的数组二分查找实现
    设计模式学习--------6.单例模式学习
    设计模式学习--------5.适配器模式学习
    tomcat 部署指南
    《Tomcat权威指南》读书笔记
    字典排序
    zabbix agentd错误日志解决办法
  • 原文地址:https://www.cnblogs.com/blog-Dr-J/p/10159895.html
Copyright © 2020-2023  润新知