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\n",ans);
162     }
163     return 0;
164 }

猜你喜欢

转载自www.cnblogs.com/letlifestop/p/10752576.html