codeforces 293E Close Vertices

题目链接

 

正解:点分治+树状数组。

 

点分治板子题,直接点分以后按照$w$排序,扫指针的时候把$w$合法的路径以$l$为下标加入树状数组统计就行了。

写这道题只是想看看我要写多久。。事实证明我确实是老年选手了,这种傻逼题写+调竟然用了$40min$。。

 

 1 #include <bits/stdc++.h>
 2 #define il inline
 3 #define RG register
 4 #define ll long long
 5 #define lb(x) (x & -x)
 6 #define N (300005)
 7 
 8 using namespace std;
 9 
10 struct edge{ int nt,to,dis; }g[N];
11 struct data{ int l,w; }st[N];
12 
13 int head[N],vis[N],dis[N],len[N],son[N],sz[N],c[N],l,w,n,num,top;
14 ll ans;
15 
16 il int gi(){
17   RG int x=0,q=1; RG char ch=getchar();
18   while ((ch<'0' || ch>'9') && ch!='-') ch=getchar();
19   if (ch=='-') q=-1,ch=getchar();
20   while (ch>='0' && ch<='9') x=x*10+ch-'0',ch=getchar();
21   return q*x;
22 }
23 
24 il void insert(RG int from,RG int to,RG int dis){
25   g[++num]=(edge){head[from],to,dis},head[from]=num; return;
26 }
27 
28 il int cmp(const data &a,const data &b){ return a.w<b.w; }
29 
30 il void add(RG int x,RG int v){
31   if (!x) c[0]+=v; else for (;x<=n;x+=lb(x)) c[x]+=v; return;
32 }
33 
34 il int query(RG int x){
35   RG int res=c[0]; for (;x;x^=lb(x)) res+=c[x]; return res;
36 }
37 
38 il void getrt(RG int x,RG int p,RG int &rt){
39   son[x]=0,sz[x]=1;
40   for (RG int i=head[x],v;i;i=g[i].nt){
41     v=g[i].to; if (v==p || vis[v]) continue;
42     getrt(v,x,rt),sz[x]+=sz[v],son[x]=max(son[x],sz[v]);
43   }
44   son[x]=max(son[x],son[0]-sz[x]);
45   if (son[rt]>=son[x]) rt=x; return;
46 }
47 
48 il void getdis(RG int x,RG int p){
49   st[++top]=(data){len[x],dis[x]},sz[x]=1;
50   for (RG int i=head[x],v;i;i=g[i].nt){
51     v=g[i].to; if (v==p || vis[v]) continue;
52     len[v]=len[x]+1,dis[v]=dis[x]+g[i].dis;
53     getdis(v,x),sz[x]+=sz[v];
54   }
55   return;
56 }
57 
58 il void calc(RG int rt,RG int llim,RG int wlim,RG int fg){
59   len[rt]=llim,dis[rt]=wlim,getdis(rt,top=0);
60   sort(st+1,st+top+1,cmp); RG int p=1;
61   for (RG int i=top;i;--i){
62     while (p<=top && st[p].w+st[i].w<=w) add(st[p++].l,1);
63     if (l>=st[i].l) ans+=fg*query(l-st[i].l);
64   }
65   for (RG int i=1;i<p;++i) add(st[i].l,-1); return;
66 }
67 
68 il void solve(RG int x,RG int S){
69   RG int rt=0; son[0]=S,getrt(x,0,rt),vis[rt]=1,calc(rt,0,0,1);
70   for (RG int i=head[rt];i;i=g[i].nt)
71     if (!vis[g[i].to]) calc(g[i].to,1,g[i].dis,-1);
72   for (RG int i=head[rt];i;i=g[i].nt)
73     if (!vis[g[i].to]) solve(g[i].to,sz[g[i].to]);
74   return;
75 }
76 
77 int main(){
78 #ifndef ONLINE_JUDGE
79   freopen("vertices.in","r",stdin);
80   freopen("vertices.out","w",stdout);
81 #endif
82   n=gi(),l=gi(),w=gi();
83   for (RG int i=2,p,d;i<=n;++i)
84     p=gi(),d=gi(),insert(p,i,d),insert(i,p,d);
85   solve(1,n),cout<<(ans-n)/2; return 0;
86 }

 

posted @ 2018-03-08 13:49  wfj_2048  阅读(227)  评论(0编辑  收藏  举报