• Distance on the tree(数剖 + 主席树)


     题目链接:https://nanti.jisuanke.com/t/38229

    题目大意:给你n个点,n-1条边,然后是m次询问,每一次询问给你u,v,w然后问你从u -> v 的路径上有多少边是小于等于w的、

    AC代码:

      1 #include<iostream>
      2 #include<cmath>
      3 #include<stack>
      4 #include<queue>
      5 #include<stdio.h>
      6 #include<string>
      7 #include<cstring>
      8 #include<algorithm>
      9 using namespace std;
     10 # define inf 0x3f3f3f3f
     11 # define ll long long
     12 const int maxn = 3e5+100;
     13 int n,m,num,tot,cnt,totn;
     14 int a[maxn];
     15 int head[maxn];
     16 int root[maxn];
     17 struct Query
     18 {
     19     int l,r,tt;
     20 } que[maxn];
     21 struct Tree
     22 {
     23     int ls,rs,sum;
     24 } tr[maxn*16];
     25 struct Edge
     26 {
     27     int from,to,val,s;
     28 } edges[maxn<<1];
     29 void addedge(int x,int y,int z)
     30 {
     31     edges[++tot]=Edge{x,y,z,head[x]};
     32     head[x]=tot;
     33 }
     34 int d[maxn],fa[maxn],size[maxn],w[maxn];
     35 int son[maxn];
     36 int rk[maxn],kth[maxn],top[maxn];
     37 void dfs1(int u,int pre,int val)
     38 {
     39 
     40     d[u]=d[pre]+1;
     41     fa[u]=pre;
     42     size[u]=1;
     43     w[u]=val;
     44     for(int i=head[u]; i!=-1; i=edges[i].s)
     45     {
     46         Edge &e=edges[i];
     47         if(e.to==pre)
     48             continue;
     49         dfs1(e.to,u,e.val);
     50         size[u]+=size[e.to];
     51         if(size[e.to]>size[son[u]])
     52             son[u]=e.to;
     53     }
     54 }
     55 void dfs2(int u,int y)
     56 {
     57     rk[u]=++cnt;
     58     kth[cnt]=u;
     59     top[u]=y;
     60     if(son[u]==0)
     61         return ;
     62     dfs2(son[u],y);
     63     for(int i=head[u]; i!=-1; i=edges[i].s)
     64     {
     65         Edge &e=edges[i];
     66         if(e.to==son[u]||e.to==fa[u])
     67             continue;
     68         dfs2(e.to,e.to);
     69     }
     70 }
     71 void buildtree(int &x,int l,int r)
     72 {
     73     x=++totn;
     74     if(l==r)
     75         return ;
     76     int mid=(l+r)>>1;
     77     buildtree(tr[x].ls,l,mid);
     78     buildtree(tr[x].rs,mid+1,r);
     79 }
     80 void add(int &x,int last,int l,int r,int p)
     81 {
     82     x=++totn;
     83     tr[x]=tr[last];
     84     if(l==r)
     85     {
     86         tr[x].sum++;
     87         return ;
     88     }
     89     int mid=l+r>>1;
     90     if(p<=mid)
     91         add(tr[x].ls,tr[last].ls,l,mid,p);
     92     if(p> mid)
     93         add(tr[x].rs,tr[last].rs,mid+1,r,p);
     94     tr[x].sum=tr[tr[x].ls].sum+tr[tr[x].rs].sum;
     95 }
     96 int ask(int ql,int qr,int l,int r,int kk)
     97 {
     98     if(1<=l&&r<=kk)
     99         return tr[qr].sum-tr[ql].sum;
    100     int mid=l+r>>1,ans=0;
    101     if(1<=mid)
    102         ans+=ask(tr[ql].ls,tr[qr].ls,l,mid,kk);
    103     if(mid<kk)
    104         ans+=ask(tr[ql].rs,tr[qr].rs,mid+1,r,kk);
    105     return ans;
    106 }
    107 int get_sum(int x,int y,int tt)
    108 {
    109     int ans=0;
    110     int fx=top[x],fy=top[y];
    111     while(fx!=fy)
    112     {
    113         if(d[fx]<d[fy])
    114             swap(x,y),swap(fx,fy);
    115         ans+=ask(root[rk[fx]-1],root[rk[x]],1,num,tt);
    116         x=fa[fx];
    117         fx=top[x];
    118     }
    119     if(d[x]<d[y])
    120         swap(x,y);
    121     ans+=ask(root[rk[y]],root[rk[x]],1,num,tt);
    122     return ans;
    123 }
    124 int main()
    125 {
    126     scanf("%d %d",&n,&m);
    127     ll x,y,z,id,ans;
    128     for(int i=0; i<=n; i++)
    129     {
    130         head[i]=-1;
    131     }
    132     for(int i=1; i<=n-1; i++)
    133     {
    134         scanf("%d %d %d",&x,&y,&z);
    135         a[++num]=z;
    136         addedge(x,y,z);
    137         addedge(y,x,z);
    138     }
    139     for(int i=1; i<=m; i++)
    140     {
    141         scanf("%d %d %d",&que[i].l,&que[i].r,&que[i].tt);
    142         a[++num]=que[i].tt;
    143     }
    144     sort(a+1,a+num+1);
    145     num=unique(a+1,a+num+1)-a-1;
    146     dfs1(1,0,inf);
    147     dfs2(1,1);
    148     for(int i=1; i<=n; i++)
    149     {
    150         w[i]=lower_bound(a+1,a+num+1,w[i])-a;
    151     }
    152     buildtree(root[0],1,num);
    153     for(int i=1; i<=n; i++)
    154     {
    155         add(root[i],root[i-1],1,num,w[kth[i]]);
    156     }
    157     for(int i=1; i<=m; i++)
    158     {
    159         que[i].tt=lower_bound(a+1,a+num+1,que[i].tt)-a;
    160         int ans=get_sum(que[i].l,que[i].r,que[i].tt);
    161         printf("%d
    ",ans);
    162     }
    163     return 0;
    164 }
  • 相关阅读:
    python读取数据写入excel
    English Study!
    ODOO里视图开发案例---定义一个像tree、form一样的视图
    更改gradle中央仓库,加快访问速度
    hadoop解决集群启动时某个slave的datanode挂掉问题
    ssh免密登录
    大数据集群脚本xcall和xsync
    虚拟机启动后黑屏并无法关闭
    快照与克隆的区别(来自转载)
    VMware12 打不开Centos6.8系统
  • 原文地址:https://www.cnblogs.com/letlifestop/p/10752576.html
Copyright © 2020-2023  润新知