zoukankan      html  css  js  c++  java
  • BZOJ4448:[SCO2015]情报传递

    题目大意:给你一棵树,有两种操作,一个是修改某个点的权值,另一个是询问两点之间的距离以及路径上小于某个值的数的个数。                                         

    询问两点之间距离直接lca即可,对于求个数的问题可以用主席树完成。                                                                                                   

      1 #include<bits/stdc++.h>
      2 using namespace std;
      3 inline int read(){
      4     int s=0;char ch=getchar();
      5     for(;ch<'0'||ch>'9';ch=getchar());
      6     for(;ch>='0'&&ch<='9';ch=getchar())s=s*10+ch-'0';
      7     return s;
      8 }
      9 int N,Q;
     10 struct node{
     11     int opt,x,y,c,t;
     12 }q[200010];
     13 int to[200010],next[200010],tot,h[200010];
     14 int root[200010],ls[4000010],rs[4000010],size[4000010];
     15 int c[200010],rt,cnt;
     16 int fa[200010][19],dep[200010];
     17 void add(int x,int y){
     18     tot++;to[tot]=y;next[tot]=h[x];h[x]=tot;
     19 }
     20 void insert(int l,int r,int Ort,int Nrt,int x){
     21     if(l==r){size[Nrt]=size[Ort]+1;return;}
     22     int mid=(l+r)>>1;
     23     if(x<=mid){
     24         ls[Nrt]=++cnt;
     25         rs[Nrt]=rs[Ort];
     26         insert(l,mid,ls[Ort],ls[Nrt],x);
     27     }else{
     28         rs[Nrt]=++cnt;
     29         ls[Nrt]=ls[Ort];
     30         insert(mid+1,r,rs[Ort],rs[Nrt],x);
     31     }
     32     size[Nrt]=size[ls[Nrt]]+size[rs[Nrt]];
     33 }
     34 void dfs(int x){
     35     for(int i=1;i<=18;++i)
     36         if(dep[x]<(1<<i))break;
     37         else fa[x][i]=fa[fa[x][i-1]][i-1];
     38     for(int i=h[x];i;i=next[i]){
     39         int v=to[i];
     40         if(dep[v])continue;
     41         dep[v]=dep[x]+1;
     42         fa[v][0]=x;
     43         if(c[v])insert(1,Q,root[x],root[v]=++cnt,c[v]);
     44         else root[v]=root[x];
     45         dfs(v);
     46     }
     47 }
     48 void init(){
     49     N=read();
     50     for(int i=1;i<=N;++i){
     51         int x=read();
     52         if(x==0)rt=i;
     53         else add(x,i);
     54     }
     55     Q=read();
     56     for(int i=1;i<=Q;++i){
     57         q[i].opt=read();
     58         if(q[i].opt==1)q[i].x=read(),q[i].y=read(),q[i].c=read();
     59         else{
     60             q[i].t=read();
     61             if(!c[q[i].t])c[q[i].t]=i;
     62         }
     63     }
     64     dep[rt]=1;
     65     if(c[rt])insert(1,Q,root[0],root[rt]=++cnt,c[rt]);
     66     dfs(rt);
     67 }
     68 int lca(int x,int y){
     69     if(dep[x]<dep[y])swap(x,y);
     70     int d=dep[x]-dep[y];
     71     for(int i=0;i<=18;++i)
     72         if(d&(1<<i))
     73             x=fa[x][i];
     74     if(x==y)return x;
     75     for(int i=18;i>=0;--i)
     76         if(fa[x][i]!=fa[y][i])
     77             x=fa[x][i],y=fa[y][i];
     78     if(x==y)return x;
     79     return fa[x][0];
     80 }
     81 int ask(int l,int r,int rrt,int lrt,int x){
     82     if(x<=0)return 0;
     83     if(l==r)return size[rrt]-size[lrt];
     84     int mid=(l+r)>>1;
     85     if(x<=mid)return ask(l,mid,ls[rrt],ls[lrt],x);
     86     else return size[ls[rrt]]-size[ls[lrt]]+ask(mid+1,r,rs[rrt],rs[lrt],x);
     87 }
     88 void work(){
     89     for(int i=1;i<=Q;++i){
     90         if(q[i].opt==1){
     91             int k=lca(q[i].x,q[i].y);
     92             int k1=dep[q[i].x]+dep[q[i].y]-2*dep[k]+1;
     93             int k2=ask(1,Q,root[q[i].x],root[fa[k][0]],i-q[i].c-1)+ask(1,Q,root[q[i].y],root[k],i-q[i].c-1);
     94             printf("%d %d
    ",k1,k2);
     95         }
     96     }
     97 }
     98 int main(){
     99     init();
    100     work();
    101     return 0;
    102 }
    View Code
  • 相关阅读:
    Web服务器讲解与JavaWeb应用部署(本机,以Tomcat为例)
    DNS与DNS劫持原理、IP、域名、服务器访问浅讲
    MyArrayList——自己实现ArrayList
    Map排序——按key排序,按value排序
    储存对象并按对象某属性排序的几种方法
    常用集合类使用方法
    避免窗口切换闪烁——卡片式布局的使用方法
    [Netbeans]为面板设置背景图片
    JDBC编程之预编译SQL与防注入式攻击以及PreparedStatement的使用教程
    JDBC编程之事务的使用教程
  • 原文地址:https://www.cnblogs.com/117208-/p/5333695.html
Copyright © 2011-2022 走看看