zoukankan      html  css  js  c++  java
  • 【BZOJ3730】震波

    题意:

    Description

    在一片土地上有N个城市,通过N-1条无向边互相连接,形成一棵树的结构,相邻两个城市的距离为1,其中第i个城市的价值为value[i]。
    不幸的是,这片土地常常发生地震,并且随着时代的发展,城市的价值也往往会发生变动。
    接下来你需要在线处理M次操作:
    0 x k 表示发生了一次地震,震中城市为x,影响范围为k,所有与x距离不超过k的城市都将受到影响,该次地震造成的经济损失为所有受影响城市的价值和。
    1 x y 表示第x个城市的价值变成了y。
    为了体现程序的在线性,操作中的x、y、k都需要异或你程序上一次的输出来解密,如果之前没有输出,则默认上一次的输出为0。

    Input

    第一行包含两个正整数N和M。
    第二行包含N个正整数,第i个数表示value[i]。
    接下来N-1行,每行包含两个正整数u、v,表示u和v之间有一条无向边。
    接下来M行,每行包含三个数,表示M次操作。
    $1leq N,Mleq 100000$
    $1leq u,v,xleq N$
    $1leq value[i],yleq 10000$
    $0leq kleq N-1$

    Output

    包含若干行,对于每个询问输出一行一个正整数表示答案。

    题解:

    动态点分治裸题……

    今天终于弄清楚动态点分治是啥玩意了……就是用数据结构爬点分树,大致感觉其实跟树链剖分差不多?(依稀记得我貌似还有个紫荆花之恋的大坑?!)

    这题用RMQLCA+线段树随便维护一下就好了……

    ps:我写的ST表求LCA+线段树跑了1600ms……卡常数の不能……orzlhx树状数组+神秘优化跑了543ms

    代码:

      1 #include<algorithm>
      2 #include<iostream>
      3 #include<cstring>
      4 #include<cstdio>
      5 #include<cmath>
      6 #include<queue>
      7 #define inf 2147483647
      8 #define eps 1e-9
      9 using namespace std;
     10 typedef long long ll;
     11 struct edge{
     12     int v,next;
     13 }a[200001];
     14 struct node{
     15     int v,ls,rs;
     16 }t[20000001];
     17 int n,m,op,u,v,x,y,S,rt,ans=0,tot=0,tim=0,cnt=0,num[100001],f[100001],rt1[100001],rt2[100001],head[100001],mx[100001],dep[100001],siz[100001],dfn[100001],st[200001][18],lg[200001];
     18 bool used[100001];
     19 void add(int u,int v){
     20     a[++tot].v=v;
     21     a[tot].next=head[u];
     22     head[u]=tot;
     23 }
     24 void updata(int l,int r,int &u,int p,int x){
     25     if(!u)u=++cnt;
     26     t[u].v+=x;
     27     if(l==r)return;
     28     int mid=(l+r)/2;
     29     if(p<=mid)updata(l,mid,t[u].ls,p,x);
     30     else updata(mid+1,r,t[u].rs,p,x);
     31 }
     32 int query(int l,int r,int u,int p){
     33     if(!u)return 0;
     34     if(l==r)return t[u].v;
     35     int mid=(l+r)/2;
     36     if(p<=mid)return query(l,mid,t[u].ls,p);
     37     else return query(mid+1,r,t[u].rs,p)+t[t[u].ls].v;
     38 }
     39 int getdis(int u,int v){
     40     int l=dep[u]+dep[v],tmp;
     41     u=dfn[u];
     42     v=dfn[v];
     43     if(u>v)swap(u,v);
     44     tmp=lg[v-u+1];
     45     return l-min(st[u][tmp],st[v-(1<<tmp)+1][tmp])*2;
     46 }
     47 void dfs(int u,int fa,int dpt){
     48     dfn[u]=++tim;
     49     dep[u]=dpt;
     50     st[tim][0]=dep[u];
     51     for(int tmp=head[u];tmp!=-1;tmp=a[tmp].next){
     52         int v=a[tmp].v;
     53         if(v!=fa){
     54             dfs(v,u,dpt+1);
     55             st[++tim][0]=dep[u];
     56         }
     57     }
     58 }
     59 void getrt(int u,int fa){
     60     siz[u]=1;
     61     mx[u]=0;
     62     for(int tmp=head[u];tmp!=-1;tmp=a[tmp].next){
     63         int v=a[tmp].v;
     64         if(v!=fa&&!used[v]){
     65             getrt(v,u);
     66             siz[u]+=siz[v];
     67             mx[u]=max(mx[u],siz[v]);
     68         }
     69     }
     70     mx[u]=max(mx[u],S-mx[u]);
     71     if(mx[u]<mx[rt])rt=u;
     72 }
     73 void getn(int u,int fa,int ls){
     74     updata(0,n-1,rt1[ls],getdis(u,ls),num[u]);
     75     if(f[ls])updata(0,n-1,rt2[ls],getdis(u,f[ls]),num[u]);
     76     siz[u]=1;
     77     for(int tmp=head[u];tmp!=-1;tmp=a[tmp].next){
     78         int v=a[tmp].v;
     79         if(v!=fa&&!used[v]){
     80             getn(v,u,ls);
     81             siz[u]+=siz[v];
     82         }
     83     }
     84 }
     85 void divide(int u){
     86     getn(u,0,u);
     87     used[u]=true;
     88     for(int tmp=head[u];tmp!=-1;tmp=a[tmp].next){
     89         int v=a[tmp].v;
     90         if(!used[v]){
     91             S=siz[v];
     92             rt=0;
     93             getrt(v,0);
     94             f[rt]=u;
     95             divide(rt);
     96         }
     97     }
     98 }
     99 void LHX_AK_IOI(int u,int k){
    100     for(int now=u;now;now=f[now]){
    101         updata(0,n-1,rt1[now],getdis(u,now),k-num[u]);
    102         if(f[now])updata(0,n-1,rt2[now],getdis(u,f[now]),k-num[u]);
    103     }
    104     num[u]=k;
    105 }
    106 int LHX_AK_NOI(int u,int k){
    107     int ret=0;
    108     for(int now=u;now;now=f[now]){
    109         if(getdis(u,now)<=k)ret+=query(0,n-1,rt1[now],k-getdis(u,now));
    110         if(f[now]&&getdis(u,f[now])<=k)ret-=query(0,n-1,rt2[now],k-getdis(u,f[now]));
    111     }
    112     return ret;
    113 }
    114 int main(){
    115     memset(head,-1,sizeof(head));
    116     scanf("%d%d",&n,&m);
    117     for(int i=1;i<=n;i++)scanf("%d",&num[i]);
    118     for(int i=1;i<n;i++){
    119         scanf("%d%d",&u,&v);
    120         add(u,v);
    121         add(v,u);
    122     }
    123     dfs(1,0,1);
    124     lg[0]=-1;
    125     for(int i=1;i<=tim;i++)lg[i]=lg[i>>1]+1;
    126     for(int i=1;(1<<i)<=tim;i++){
    127         for(int j=1;j<=tim-(1<<i)+1;j++){
    128             st[j][i]=min(st[j][i-1],st[j+(1<<i-1)][i-1]);
    129         }
    130     }
    131     mx[rt=0]=inf;
    132     S=n;
    133     getrt(1,0);
    134     divide(rt);
    135     for(int i=1;i<=m;i++){
    136         scanf("%d%d%d",&op,&x,&y);
    137         x^=ans,y^=ans;
    138         if(op==0){
    139             ans=LHX_AK_NOI(x,y);
    140             printf("%d
    ",ans);
    141         }else LHX_AK_IOI(x,y);
    142     }
    143     return 0;
    144 }
  • 相关阅读:
    软件工程作业03
    PSP0级要求02
    PSP0级要求日志
    软件工程个人作业02
    第三周学习进度
    第二周学习进度
    软件工程个人作业01
    Web网页登录设计
    第一周学习进度
    第三周学习进度条+PSP0过程文档
  • 原文地址:https://www.cnblogs.com/dcdcbigbig/p/9858815.html
Copyright © 2011-2022 走看看