• 【CODECHEF】Children Trips 倍增


    此题绝了,$O(n^{1.5} log n)$都可以过掉。。。。

    题目大意:给你一颗$n$个点的树,每条边边权不是2就是$1$,有$m$个询问,每次询问一个人从$x$点走到$y$点,每天可以走的里程数不超过$k$,问你从$x$至$y$至少需几天。

    数据范围:$n≤10^5$。

    我们将询问分成$k≤sqrt{n}$和k$>sqrt{n}$两类。

    对于$k>sqrt{n}$的,每次跳跃我们直接大力倍增就可以了,不难发现此方法单次的时间复杂度为$O(sqrt{n}log  n)$。

    对于$k≤sqrt{n}$的,我们将$k$相同的分为一类,令$g[i][j]$表示从i往根走$2^j$天走到的位置,然后大力倍增就可以了,不难发现单次倍增找答案的时间复杂度是$O(log n)$的,重建一次倍增数组的时间复杂度是$O(n log  n)$的,总时间复杂度为$O(n^{1.5} log n+m log n)$。

    如此粗暴的做法居然能在$350ms$跑过去,真是绝了(敢写敢过。。。。)

     1 #include<bits/stdc++.h>
     2 #define M 100005
     3 #define N 17
     4 using namespace std;
     5 struct edge{int u,v,next;}e[M*2]={0}; int head[M]={0},use=0;
     6 void add(int x,int y,int z){use++;e[use].u=y;e[use].v=z;e[use].next=head[x];head[x]=use;}
     7 int f[M][N]={0},dep[M]={0},dis[M]={0};
     8 void dfs(int x,int fa,int hh){
     9     f[x][0]=fa; dep[x]=dep[fa]+1; dis[x]=dis[fa]+hh;
    10     for(int i=1;i<N;i++) f[x][i]=f[f[x][i-1]][i-1];
    11     for(int i=head[x];i;i=e[i].next) if(e[i].u!=fa) dfs(e[i].u,x,e[i].v);
    12 }
    13 int getlca(int x,int y){
    14     if(dep[x]<dep[y]) swap(x,y); int cha=dep[x]-dep[y];
    15     for(int i=N-1;~i;i--) if((1<<i)&cha) x=f[x][i];
    16     for(int i=N-1;~i;i--) if(f[x][i]!=f[y][i]) x=f[x][i],y=f[y][i];
    17     if(x==y) return x; return f[x][0];
    18 }
    19 int getdis(int x,int y){return dis[x]+dis[y]-2*dis[getlca(x,y)];}
    20 int _j=0;
    21 int jumpdn(int x,int y,int d){
    22     int now=dis[y]-dis[x]; if(now<=d) return y;
    23     for(int i=N-1;~i;i--) 
    24     if(dis[f[y][i]]-dis[x]>=d) 
    25     y=f[y][i];
    26     if(dis[y]-dis[x]>d) y=f[y][0];
    27     return y;
    28 }
    29 int jumpup(int x,int y,int d){
    30     if(y){
    31         int lca=getlca(x,y); _j=0;
    32         if(dis[x]-dis[lca]<=d){
    33             d-=dis[x]-dis[lca]; _j=1;
    34             return jumpdn(lca,y,d);
    35         }
    36     }
    37     for(int i=N-1;~i;i--) if(dis[x]-dis[f[x][i]]<=d) d-=dis[x]-dis[f[x][i]],x=f[x][i];
    38     return x;
    39 }
    40 int g[M][N]={0},D=0;
    41 void dfs(int x,int fa){
    42     g[x][0]=jumpup(x,0,D); for(int i=1;i<N;i++) g[x][i]=g[g[x][i-1]][i-1];
    43     for(int i=head[x];i;i=e[i].next) if(e[i].u!=fa) dfs(e[i].u,x);
    44 }
    45 int query(int &x,int lca){int res=0;
    46     for(int i=N-1;~i;i--){
    47         if(dis[x]-dis[lca]<D) return res;
    48         if(dep[g[x][i]]>=dep[lca]) x=g[x][i],res+=1<<i;
    49     }
    50     return res;
    51 }
    52 int n,m,sq;
    53 struct ask{
    54     int x,y,d,id; ask(){x=y=d=id=0;}
    55     void rd(int ID){id=ID; scanf("%d%d%d",&x,&y,&d);}
    56     friend bool operator <(ask a,ask b){return a.d<b.d;}
    57     int query1(){
    58         if(x==y) return 0;
    59         int lca=getlca(x,y),res=0; _j=0;
    60         while(_j==0) x=jumpup(x,y,d),res++;
    61         while(x!=y) x=jumpdn(x,y,d),res++;
    62         return res;
    63     }
    64     int query2(){
    65         int lca=getlca(x,y),res=0;
    66         if(D!=d){D=d;dfs(1,0);}
    67         res+=query(x,lca);
    68         res+=query(y,lca);
    69         res+=(getdis(x,y)>D)+(getdis(x,y)>0);
    70         return res;
    71     }
    72 }p[M]; int ans[M]={0};
    73 int main(){
    74     scanf("%d",&n); sq=(n<=1000?0:10);
    75     for(int i=1,x,y,z;i<n;i++) scanf("%d%d%d",&x,&y,&z),add(x,y,z),add(y,x,z);
    76     dfs(1,0,0); dis[0]=-1;
    77     scanf("%d",&m);
    78     for(int i=1;i<=m;i++) p[i].rd(i);
    79     sort(p+1,p+m+1);
    80     for(int i=1;i<=m;i++){
    81         if(p[i].d<=sq) ans[p[i].id]=p[i].query2();
    82         else ans[p[i].id]=p[i].query1();
    83     }
    84     for(int i=1;i<=m;i++) printf("%d
    ",ans[i]);
    85 }
  • 相关阅读:
    弹性网卡支持私网多IP
    微服务浪潮中,程序猿如何让自己 Be Cloud Native
    Nacos v0.7.0:对接CMDB,实现基于标签的服务发现能力
    如何更高效的管理原生微服务应用
    如何在 Intellij IDEA 更高效地将应用部署到容器服务 Kubernetes
    PHP flock文件锁
    MySQL锁(MyISAM和InnoDB)
    汽车操作系统革命:封闭还是开源?
    采集百度top500歌曲,python2.7.2
    关于revision 的cover letter
  • 原文地址:https://www.cnblogs.com/xiefengze1/p/10353203.html
Copyright © 2020-2023  润新知