BZOJ 1468 & 点分治
题意:
带权树,求距离小于k的点对数目。
SOL:
参考http://blog.csdn.net/jiangshibiao/article/details/25738041解决了题意问题。。。
代码是看着iwtwiioi巨巨打的。。。因为查错然后改得几乎一模一样。。。
当然这种分治问题自然还是要安利qzc巨巨的论文= =名字忘了。。。
其实还是很明朗的方法,就是觉得树上容斥有点6.
恩好像就没什么了。
Code:
/*========================================================================== # Last modified: 2016-03-11 11:50 # Filename: t2.cpp # Description: ==========================================================================*/ #define me AcrossTheSky #include <cstdio> #include <cmath> #include <ctime> #include <string> #include <cstring> #include <cstdlib> #include <iostream> #include <algorithm> #include <set> #include <map> #include <stack> #include <queue> #include <vector> #define lowbit(x) (x)&(-x) #define FOR(i,a,b) for((i)=(a);(i)<=(b);(i)++) #define FORP(i,a,b) for(int i=(a);i<=(b);i++) #define FORM(i,a,b) for(int i=(a);i>=(b);i--) #define rdm(x, i) for(int i=ihead[x]; i; i=e[i].next) #define ls(a,b) (((a)+(b)) << 1) #define rs(a,b) (((a)+(b)) >> 1) #define getlc(a) ch[(a)][0] #define getrc(a) ch[(a)][1] #define maxn 100000 #define maxm 100000 #define pi 3.1415926535898 #define _e 2.718281828459 #define INF 1070000000 using namespace std; typedef long long ll; typedef unsigned long long ull; template<class T> inline void read(T& num) { bool start=false,neg=false; char c; num=0; while((c=getchar())!=EOF) { if(c=='-') start=neg=true; else if(c>='0' && c<='9') { start=true; num=num*10+c-'0'; } else if(start) break; } if(neg) num=-num; } /*==================split line==================*/ const int N=40005; int ihead[N], cnt, K; struct Edge{ int next, to, w; }e[N<<1]; void add(int u, int v, int w) { e[++cnt].next=ihead[u]; ihead[u]=cnt; e[cnt].to=v; e[cnt].w=w; e[++cnt].next=ihead[v]; ihead[v]=cnt; e[cnt].to=u; e[cnt].w=w; } int dep[N], d[N], cdep, ans, mn; int root, sz[N], vis[N]; void getroot(int x, int fa, int sum) { sz[x]=1; int y, mx=0; rdm(x, i) if(!vis[y=e[i].to] && e[i].to!=fa) { getroot(y, x, sum); sz[x]+=sz[y]; mx=max(mx, sz[y]); } mx=max(mx, sum-mx); if(mx<mn) mn=mx, root=x; } void getdep(int x, int fa) { dep[++cdep]=d[x]; int y; //printf("x:%d\tfa:%d\tdep:%d\n", x, fa, dep[x]); rdm(x, i) if(!vis[y=e[i].to] && e[i].to!=fa) { d[y]=d[x]+e[i].w; getdep(y, x); } } int cal(int x, int last=0) { cdep=0; d[x]=last; getdep(x, -1); int ret=0, front=1, tail=cdep; sort(dep+1, dep+1+cdep); while(front<tail) { while(front<tail && dep[tail]+dep[front]>K) --tail; ret+=tail-front; ++front; } return ret; } void dfs(int x, int all) { vis[x]=1; int y; ans+=cal(x); //printf("root:%d\n", x); rdm(x, i) if(!vis[y=e[i].to]) { ans-=cal(y, e[i].w); int s=sz[y]>sz[x]?all-sz[x]:sz[y]; root=0; mn=INF; getroot(y, x, s); dfs(root, s); } } int main() { int n; read(n); FORP(i,1,n-1) { int u,v,w; read(u); read(v); read(w); add(u,v,w); } read(K); mn=INF; getroot((n+1)>>1, -1, n); dfs(root, n); printf("%d\n", ans); return 0; }
Sometimes it s the very people who no one imagines anything of. who do the things that no one can imagine.