• 牛客网9.9比赛 C 保护


    题目大意:

    n个城市构成一个树 m支军队 每只军队守卫 在xi到yi的最短路径上的城市

    q个重要人物从vi出发 找到离根最近的点使从vi到这个点上所有路径都可以被至少ki个军队完全覆盖

    输出每个答案的点的深度

    思路:

    对于每个军队 可以拆成两个链

    在深度较大的节点的权值线段树上把深度较低的点+1

    然后合并线段树

    查询的时候查询子树线段树中第k小的

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cmath>
     4 #include<cstdlib>
     5 #include<cstring>
     6 #include<algorithm>
     7 #include<vector>
     8 #include<queue>
     9 #include<map>
    10 #define inf 2139062143
    11 #define ll long long
    12 #define MAXN 200100
    13 using namespace std;
    14 inline int read()
    15 {
    16     int x=0,f=1;char ch=getchar();
    17     while(!isdigit(ch)) {if(ch=='-') f=-1;ch=getchar();}
    18     while(isdigit(ch)) {x=x*10+ch-'0';ch=getchar();}
    19     return x*f;
    20 }
    21 int n,m,f[MAXN][18],dep[MAXN],hsh[MAXN],sz[MAXN],val[MAXN<<6];
    22 int nxt[MAXN<<1],fst[MAXN],to[MAXN<<1],cnt,rt[MAXN],ls[MAXN<<6],rs[MAXN<<6];
    23 void add(int u,int v) {nxt[++cnt]=fst[u],fst[u]=cnt,to[cnt]=v;}
    24 void dfs(int x)
    25 {
    26     hsh[x]=++cnt,sz[x]=1;
    27     for(int i=1;(1<<i)<=dep[x];i++) f[x][i]=f[f[x][i-1]][i-1];
    28     for(int i=fst[x];i;i=nxt[i])
    29         if(to[i]!=f[x][0]){dep[to[i]]=dep[x]+1,f[to[i]][0]=x;dfs(to[i]);sz[x]+=sz[to[i]];}
    30 }
    31 int lca(int u,int v)
    32 {
    33     if(dep[u]<dep[v]) swap(u,v);
    34     int t=dep[u]-dep[v];
    35     for(int i=0;i<=17;i++)
    36         if((1<<i)&t) u=f[u][i];
    37     if(u==v) return u;
    38     for(int i=17;i>=0;i--)
    39         if(f[u][i]!=f[v][i]) u=f[u][i],v=f[v][i];
    40     return f[u][0];
    41 }
    42 void inst(int &k,int l,int r,int x)
    43 {
    44     if(!k) k=++cnt;
    45     val[k]++;
    46     if(l==r) return ;
    47     int mid=(l+r)>>1;
    48     if(x<=mid) inst(ls[k],l,mid,x);
    49     else inst(rs[k],mid+1,r,x);
    50 }
    51 void merge(int &a,int b)
    52 {
    53     if(!a) {a=b;return ;}
    54     if(!b) return ;
    55     val[a]+=val[b];
    56     merge(ls[a],ls[b]);
    57     merge(rs[a],rs[b]);
    58 }
    59 int query(int k1,int k2,int l,int r,int a,int b)
    60 {
    61     if(!k1) return 0;
    62     if(l==a&&r==b) return val[k1]-val[k2];
    63     int mid=(l+r)>>1;
    64     if(b<=mid) return query(ls[k1],ls[k2],l,mid,a,b);
    65     else if(a>mid) return query(rs[k1],rs[k2],mid+1,r,a,b);
    66     else return query(ls[k1],ls[k2],l,mid,a,mid)+query(rs[k1],rs[k2],mid+1,r,mid+1,b);
    67 }
    68 int ans(int k1,int k2,int l,int r,int x)
    69 {
    70     //cout<<l<<" "<<r<<" "<<val[k1]-val[k2]<<" "<<x<<endl;
    71     if(l==r) return l;
    72     int mid=(l+r)>>1;
    73     if(x<=val[ls[k1]]-val[ls[k2]]) return ans(ls[k1],ls[k2],l,mid,x);
    74     else return ans(rs[k1],rs[k2],mid+1,r,x-val[ls[k1]]+val[ls[k2]]);
    75 }
    76 int main()
    77 {
    78     n=read(),m=read();int a,b,c;
    79     for(int i=1;i<n;i++) {a=read(),b=read();add(a,b);add(b,a);}
    80     cnt=0;dfs(1);cnt=0;
    81     while(m--)
    82     {
    83         a=read(),b=read(),c=lca(a,b);
    84         inst(rt[hsh[a]],1,n,dep[c]+1);
    85         inst(rt[hsh[b]],1,n,dep[c]+1);
    86     }
    87     for(int i=1;i<=n;i++) merge(rt[i],rt[i-1]);
    88     m=read();
    89     while(m--)
    90     {
    91         a=read(),b=read();
    92         //cout<<query(rt[hsh[a]+sz[a]-1],rt[hsh[a]-1],1,n,1,dep[a]+1)<<endl;
    93         if(query(rt[hsh[a]+sz[a]-1],rt[hsh[a]-1],1,n,1,dep[a]+1)<b) puts("0");
    94         else printf("%d
    ",dep[a]+1-ans(rt[hsh[a]+sz[a]-1],rt[hsh[a]-1],1,n,b));
    95     }
    96 }
    View Code
  • 相关阅读:
    集合类List,set,Map 的遍历方法,用法和区别
    如何优化sql语句
    io流(详询请加qq:2085920154)
    Servlet过滤器(详询请加qq:2085920154)
    oracle,sqlserver同一个表两个字段和成一个列查询 (详询请加qq:2085920154)
    SQL SERVER 将表中字符串转换为数字的函数 (详询请加qq:2085920154)
    SQL SERVER增加、删除、更改表中的字段名 (详询请加qq:2085920154)
    SQL Server日期时间格式转换字符串详解 (详询请加qq:2085920154)
    把文件打成zip或然rar下载 (详询请加qq:2085920154)
    计算机网络-校招总结
  • 原文地址:https://www.cnblogs.com/yyc-jack-0920/p/9637348.html
Copyright © 2020-2023  润新知