zoukankan      html  css  js  c++  java
  • 震波

    在一片土地上有 $N$ 个城市,通过 $N-1$ 条无向边互相连接,形成一棵树的结构,相邻两个城市的距离为 $1$,其中第 $i$ 个城市的价值为 $value[i]$。
    不幸的是,这片土地常常发生地震,并且随着时代的发展,城市的价值也往往会发生变动。
    接下来你需要在线处理 $M$ 次操作:
    - $0~x~k$ 表示发生了一次地震,震中城市为 $x$ ,影响范围为 $k$ ,所有与 $x$ 距离不超过 $k$ 的城市都将受到影响,该次地震造成的经济损失为所有受影响城市的价值和。
    - $1~x~y$ 表示第$x$个城市的价值变成了 $y$ 。
    为了体现程序的在线性,操作中的 $x$ 、$y$ 、$k$ 都需要异或你程序上一次的输出来解密,如果之前没有输出,则默认上一次的输出为 $0$ 。
     
     
     
     
    Solution
    考虑建出点分树,每一个点开一棵以长度为下标的线段树。
    查询时可以一步步往上跳。假设他到父亲的权值为t,每此查询与x距离为k k+t ...的点。
    可是这样会算重。
    那么可以在每个点再开一棵线段树,下标为点到他点分树上父亲的权值。
    每次减去第二棵线段树中k+t的值。也就是自己与父亲相同的贡献
    卡常毒题
    orz邵神树状数组常树优秀
     
      1 #include<cstdio>
      2 #include<iostream>
      3 #include<cstdlib>
      4 #include<cstring>
      5 #include<algorithm>
      6 #include<cmath>
      7 #define maxn 200006
      8 using namespace std;
      9 int n,m,head[maxn],a[maxn],val[maxn],siz,tot,deep[maxn];
     10 int f[maxn],vis[maxn],par[maxn],sz[maxn],rt;
     11 int cnt,root[maxn],st[maxn][20],sc,dfn[maxn],l2[maxn];
     12 struct node{
     13     int v,nex;
     14 }e[maxn];
     15 struct no{
     16     int ls,rs,v;
     17 }tr[maxn*140];
     18 inline void lca(int k,int fa){
     19     st[dfn[k]=++sc][0]=deep[k]=deep[fa]+1;
     20     for(int i=head[k];i;i=e[i].nex)if(e[i].v!=fa)lca(e[i].v,k),st[++sc][0]=deep[k];
     21 }
     22 inline void add(int &k,int l,int r,int pl,int v){
     23     if(!k)k=++cnt;
     24     if(l==r){tr[k].v+=v;return;}
     25     int mid=l+r>>1;
     26     if(pl<=mid)add(tr[k].ls,l,mid,pl,v);
     27     else add(tr[k].rs,mid+1,r,pl,v);
     28     tr[k].v=tr[tr[k].ls].v+tr[tr[k].rs].v;
     29 }
     30 inline int ask(int k,int l,int r,int pl){
     31     if(!k||pl<0)return 0;
     32     if(l==r)return tr[k].v;
     33     int mid=l+r>>1;
     34     if(pl<=mid)return ask(tr[k].ls,l,mid,pl);
     35     else return tr[tr[k].ls].v+ask(tr[k].rs,mid+1,r,pl);
     36     
     37 }
     38 inline int dis(int x,int y){
     39     if(dfn[y]<dfn[x])swap(x,y);
     40     int i=l2[dfn[y]-dfn[x]+1];
     41     int dl=min(st[dfn[x]][i],st[dfn[y]-(1<<i)+1][i]);
     42     return deep[x]+deep[y]-(dl<<1);
     43 }
     44 inline void dfs(int o,int la,int k,int fa){
     45     add(root[o],0,n,dis(o,k),val[k]);
     46     if(la)add(root[o+n],0,n,dis(k,la),val[k]);
     47     sz[k]=1;
     48     for(int i=head[k];i;i=e[i].nex){
     49         if(e[i].v==fa||vis[e[i].v])continue;
     50         dfs(o,la,e[i].v,k);
     51         sz[k]+=sz[e[i].v];
     52     }
     53 }
     54 inline void findr(int k,int fa){
     55     sz[k]=1;f[k]=0;
     56     for(int i=head[k];i;i=e[i].nex){
     57         if(e[i].v==fa||vis[e[i].v])continue;
     58         findr(e[i].v,k);
     59         sz[k]+=sz[e[i].v];
     60         f[k]=max(f[k],sz[e[i].v]);
     61     }
     62     f[k]=max(f[k],siz-sz[k]);
     63     if(f[k]<f[rt])rt=k;
     64 }
     65 inline void work(int k,int la){
     66     vis[k]=1;
     67     dfs(k,la,k,0);
     68     for(int i=head[k];i;i=e[i].nex){
     69         if(!vis[e[i].v]){
     70             siz=sz[e[i].v];rt=0;findr(e[i].v,k);
     71             par[rt]=k;
     72             work(rt,k);
     73         }
     74     }
     75 }
     76 inline int R(){
     77     int v=0;char ch;
     78     while(!isdigit(ch=getchar()));v=ch-48;
     79     while(isdigit(ch=getchar()))v=(v<<1)+(v<<3)+ch-48;
     80     return v;
     81 }
     82 int main()
     83 {
     84     n=R();m=R();
     85     for(int i=1;i<=n;i++)val[i]=R();
     86     for(int i=1,t1,t2;i<n;i++){
     87         t1=R();t2=R();
     88         e[++tot].v=t2;e[tot].nex=head[t1];head[t1]=tot;
     89         e[++tot].v=t1;e[tot].nex=head[t2];head[t2]=tot;
     90     }
     91     lca(1,0);
     92     for(int i=2;i<=sc;i++)l2[i]=l2[i/2]+1;
     93     for(int j=1;j<=l2[sc];j++)
     94         for(int i=1;i+(1<<j)<=sc+1;i++)st[i][j]=min(st[i][j-1],st[i+(1<<j-1)][j-1]);
     95     rt=0;f[0]=1e9;siz=n;findr(1,0);
     96     work(rt,0);
     97     int ans=0;
     98     for(int i=1,op,y,x,k;i<=m;i++){
     99         op=R();
    100         if(op==0){
    101             x=R();k=R();
    102             x^=ans,k^=ans;
    103             ans=0;int fi=x;
    104             for(int d=0;x;){
    105                 ans+=ask(root[x],0,n,k-d);d=dis(par[x],fi);
    106                 if(par[x])ans-=ask(root[n+x],0,n,k-d);
    107                 x=par[x];
    108             }
    109             printf("%d
    ",ans);
    110         }
    111         if(op==1){
    112             x=R();y=R();
    113             x^=ans;y^=ans;
    114             int fi=x;
    115             for(int d=0;x;){
    116                 add(root[x],0,n,d,y-val[fi]);d=dis(fi,par[x]);
    117                 if(par[x])add(root[n+x],0,n,d,y-val[fi]);
    118                 x=par[x];
    119             }
    120             val[fi]=y;
    121         }
    122     }
    123     return 0;
    124 }
    View Code
     

  • 相关阅读:
    eclipse中切换jdk版本
    201704 创建财务凭证函数
    201704 F-47创建预付款申请a
    201704 F-02创建财务凭证
    20170413 F110学习
    20170411 F110初始界面-建议清单
    20170411 供应商保证金维护视图
    20170411 F-02创建财务凭证
    ABAP 断点篇-001
    20170411 debug窗口执行文件
  • 原文地址:https://www.cnblogs.com/liankewei/p/10657891.html
Copyright © 2011-2022 走看看