# bzoj 1468

  1 /**************************************************************
2     Problem: 1468
3     User: idy002
4     Language: C++
5     Result: Accepted
6     Time:6536 ms
7     Memory:54384 kb
8 ****************************************************************/
9
10 #include <cstdio>
11 #include <vector>
12 #include <map>
13 #define fprintf(...)
14 #define N 40010
15 #define S 2000000
16 using namespace std;
17
18 struct Stat {
19     int c, d, s;
20     Stat( int c, int d, int s ):c(c),d(d),s(s){}
21 };
22 struct Splay {
23     static int son[S][2], pre[S], key[S], siz[S], ntot;
24     int root;
25     void init() { root=0; }
26     inline void update( int nd ) {
27         siz[nd] = siz[son[nd][0]]+siz[son[nd][1]]+1;
28     }
29     void rotate( int nd, int d ) {
30         int p=pre[nd];
31         int s=son[nd][!d];
32         int ss=son[s][d];
33
34         son[nd][!d] = ss;
35         son[s][d] = nd;
36         if( p ) son[p][ nd==son[p][1] ] = s;
37         else root = s;
38
39         pre[nd] = s;
40         pre[s] = p;
41         if( ss ) pre[ss] = nd;
42
43         update( nd );
44         update( s );
45     }
46     void splay( int nd, int top=0 ) {
47         while( pre[nd]!=top ) {
48             int p = pre[nd];
49             int nl = nd==son[p][0];
50             if( pre[p]==top ) {
51                 rotate( p, nl );
52             } else {
53                 int pp = pre[p];
54                 int pl = p==son[pp][0];
55                 if( nl==pl ) {
56                     rotate( pp, pl );
57                     rotate( p, nl );
58                 } else {
59                     rotate( p, nl );
60                     rotate( pp, pl );
61                 }
62             }
63         }
64     }
65     int newnode( int p, int k ) {
66         int nd = ++ntot;
67         son[nd][0] = son[nd][1] = 0;
68         pre[nd] = p;
69         key[nd] = k;
70         siz[nd] = 1;
71         return nd;
72     }
73     void insert( int k ) {
74         if( !root ) {
75             root = newnode( 0, k );
76             return;
77         }
78         int nd = root;
79         while( son[nd][ k>key[nd] ] ) nd=son[nd][ k>key[nd] ];
80         son[nd][ k>key[nd] ] = newnode( nd, k );
81         splay( son[nd][ k>key[nd] ] );
82     }
83     int query( int k ) {
84         int nd=root;
85         int lnd;
86         int rt = 0;
87         while(nd) {
88             lnd = nd;
89             if( key[nd]>k ) {
90                 nd = son[nd][0];
91             } else {
92                 rt += siz[son[nd][0]]+1;
93                 nd = son[nd][1];
94             }
95         }
96         splay( lnd );
97         return rt;
98     }
99 };
100 int Splay::son[S][2], Splay::pre[S], Splay::key[S], Splay::siz[S], Splay::ntot;
101
102
103 int n, qdis;
104 vector<int> g[N], ww[N];
105 vector<Stat> st[N];
106 map<int,Splay > spy[N];
107 int vis[N], anc[N], siz[N], bac[N], dis[N];
108 int qu[N], bg, ed;
109
110 void build( int rt ) {
111     /* find the core of the block containing rt */
112     qu[bg=ed=1] = rt;
113     anc[rt] = rt;
114     siz[rt] = bac[rt] = 0;
115     while( ed>=bg ) {
116         int u=qu[bg++];
117         for( int t=0; t<g[u].size(); t++ ) {
118             int v=g[u][t];
119             if( vis[v] || v==anc[u] ) continue;
120             qu[++ed] = v;
121             anc[v] = u;
122             siz[v] = bac[v] = 0;
123         }
124     }
125     for( int i=ed; i>=1; i-- ) {
126         int u=qu[i];
127         int p=anc[u];
128         siz[u]++;
129         siz[p] += siz[u];
130         if( bac[p]<siz[u] ) bac[p]=siz[u];
131     }
132     for( int i=ed; i>=1; i-- ) {
133         int u=qu[i];
134         if( bac[u]<siz[rt]-siz[u] ) bac[u]=siz[rt]-siz[u];
135     }
136     for( int i=ed; i>=1; i-- ) {
137         int u=qu[i];
138         if( bac[u]<bac[rt] ) rt=u;
139     }
140     /* statistics the info of the block */
141     spy[rt][0].init();
142     spy[rt][0].insert( 0 );
143     st[rt].push_back( Stat(rt,0,0) );
144     vis[rt] = true;
145     fprintf( stderr, "%d as core\n", rt );
146     for( int tm=0; tm<g[rt].size(); tm++ ) {
147         int r=g[rt][tm], w=ww[rt][tm];
148         if( vis[r] ) continue;
149         qu[bg=ed=1] = r;
150         anc[r] = rt;
151         dis[r] = w;
152         while( ed>=bg ) {
153             int u=qu[bg++];
154             for( int t=0; t<g[u].size(); t++ ) {
155                 int v=g[u][t], w=ww[u][t];
156                 if( vis[v] || v==anc[u] ) continue;
157                 qu[++ed] = v;
158                 anc[v] = u;
159                 dis[v] = dis[u]+w;
160             }
161         }
162         spy[rt][r].init();
163         for( int i=ed; i>=1; i-- ) {
164             int u=qu[i];
165             spy[rt][0].insert( dis[u] );
166             spy[rt][r].insert( dis[u] );
167             st[u].push_back( Stat(rt,dis[u],r) );
168         }
169         build( r );
170     }
171 }
172
173 int main() {
174     scanf( "%d", &n );
175     for( int i=1,u,v,w; i<n; i++ ) {
176         scanf( "%d%d%d", &u, &v, &w );
177         g[u].push_back( v );
178         g[v].push_back( u );
179         ww[u].push_back( w );
180         ww[v].push_back( w );
181     }
182     scanf( "%d", &qdis );
183     build(1);
184     for( int u=1; u<=n; u++ ) {
185         fprintf( stderr, "Stat of %d:\n", u );
186         for( int t=0; t<st[u].size(); t++ ) {
187             fprintf( stderr, "core=%d dis=%d subcore:%d\n", st[u][t].c, st[u][t].d, st[u][t].s );
188         }
189         fprintf( stderr, "\n" );
190     }
191
192     int ans = 0;
193     for( int u=1; u<=n; u++ ) {
194         int tans=0;
195         for( int t=0; t<st[u].size(); t++ ) {
196             Stat &s = st[u][t];
197             tans += spy[s.c][0].query( qdis-s.d )- (s.s?spy[s.c][s.s].query( qdis-s.d ):0);
198         }
199         fprintf( stderr, "%d added %d\n", u, tans-1 );
200         ans += tans-1;
201     }
202     printf( "%d\n", ans/2 );
203 }
View Code

posted @ 2015-03-26 18:35  idy002  阅读(182)  评论(0编辑  收藏  举报