luogu P4178 Tree
Posted yuyanjiab
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了luogu P4178 Tree相关的知识,希望对你有一定的参考价值。
板子ex
开始天真的以为把m组询问改成k组询问就行了
但是板子里面的两层循环求方案实在是接受不了
所以套一个树状数组统计答案就行
注意大于k的边权全都不要
Code:
1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 #define ms(a,b) memset(a,b,sizeof a) 5 #define rep(i,a,n) for(int i = a;i <= n;i++) 6 #define per(i,n,a) for(int i = n;i >= a;i--) 7 #define inf 2147483647 8 using namespace std; 9 typedef long long ll; 10 #define B puts("GG") 11 ll read() { 12 ll as = 0,fu = 1; 13 char c = getchar(); 14 while(c < ‘0‘ || c > ‘9‘) { 15 if(c == ‘-‘) fu = -1; 16 c = getchar(); 17 } 18 while(c >= ‘0‘ && c <= ‘9‘) { 19 as = as * 10 + c - ‘0‘; 20 c = getchar(); 21 } 22 return as * fu; 23 } 24 //head 25 const int N = 100003; 26 int n,m,q[N]; 27 int head[N],mo[N<<1],nxt[N<<1],cst[N<<1],cnt; 28 void addd(int x,int y,int w) { 29 nxt[++cnt] = head[x],head[x] = cnt; 30 mo[cnt] = y,cst[cnt] = w; 31 } 32 void add(int x,int y) { 33 int w = read(); 34 if(x^y) addd(x,y,w),addd(y,x,w); 35 } 36 37 int sze[N]; 38 bool vis[N]; 39 int sum,rt,maxx[N]; 40 void getroot(int x,int f) { 41 sze[x] = 1,maxx[x] = 0; 42 for(int i = head[x];i;i = nxt[i]) { 43 int sn = mo[i]; 44 if(vis[sn] || sn == f) continue; 45 getroot(sn,x),sze[x] += sze[sn]; 46 maxx[x] = max(maxx[x],sze[sn]); 47 } 48 maxx[x] = max(maxx[x],sum - sze[x]); 49 if(maxx[x] < maxx[rt]) rt = x; 50 } 51 52 int dis[N],stk[N]; 53 void getdis(int x,int f) { 54 // if(dis[x] > m) return; 55 stk[++stk[0]] = dis[x]; 56 for(int i = head[x];i;i = nxt[i]) { 57 int sn = mo[i]; 58 if(sn == f || vis[sn]) continue; 59 dis[sn] = dis[x] + cst[i]; 60 getdis(sn,x); 61 } 62 } 63 64 int t[N]; 65 #define low(x) ((x) & (-(x))) 66 void upd(int x,int k) { 67 if(x <= 0) return; 68 for(int i = x;i <= m;i += low(i)) t[i] += k; 69 } 70 int qry(int x) { 71 if(x <= 0) return 0; 72 int sum = 0; 73 for(int i = x;i;i -= low(i)) sum += t[i]; 74 return sum; 75 } 76 77 int ans; 78 int con[N]; 79 void calc(int x) { 80 for(int i = head[x];i;i = nxt[i]) { 81 int sn = mo[i]; 82 if(vis[sn]) continue; 83 stk[0] = 0,dis[sn] = cst[i],getdis(sn,x); 84 per(j,stk[0],1) ans += qry(m - stk[j]); 85 per(j,stk[0],1) { 86 if(stk[j] > m) continue; 87 con[++con[0]] = stk[j],upd(stk[j],1); 88 ans++; 89 } 90 } 91 per(i,con[0],1) upd(con[i],-1); 92 } 93 94 void solve(int x) { 95 vis[x] = 1,con[0] = 0,calc(x); 96 for(int i = head[x];i;i = nxt[i]) { 97 int sn = mo[i]; 98 if(vis[sn]) continue; 99 sum = sze[sn],maxx[rt = 0] = inf; 100 getroot(sn,sn),solve(rt); 101 } 102 } 103 104 int main() { 105 n = read(); 106 rep(i,2,n) add(read(),read()); 107 m = read(); 108 sum = n,maxx[rt = 0] = inf; 109 getroot(1,1),solve(rt); 110 printf("%d ",ans); 111 return 0; 112 }
以上是关于luogu P4178 Tree的主要内容,如果未能解决你的问题,请参考以下文章