标签:
点分治常规题。练习模板
1 //OJ 2077 2 //by Cydiater 3 //2016.9.23 4 #include <iostream> 5 #include <cstdio> 6 #include <cstring> 7 #include <string> 8 #include <algorithm> 9 #include <queue> 10 #include <map> 11 #include <ctime> 12 #include <cmath> 13 #include <iomanip> 14 #include <cstdlib> 15 using namespace std; 16 #define ll long long 17 #define up(i,j,n) for(int i=j;i<=n;i++) 18 #define down(i,j,n) for(int i=j;i>=n;i--) 19 const int MAXN=1e6+5; 20 const int oo=0x3f3f3f3f; 21 inline int read(){ 22 char ch=getchar();int x=0,f=1; 23 while(ch>‘9‘||ch<‘0‘){if(ch==‘-‘)f=-1;ch=getchar();} 24 while(ch>=‘0‘&&ch<=‘9‘){x=x*10+ch-‘0‘;ch=getchar();} 25 return x*f; 26 } 27 int LINK[MAXN],len=0,sum,max_siz[MAXN],root,siz[MAXN],dis[MAXN],head,tail,q[MAXN],cnt[3],ans=0; 28 bool vis[MAXN]; 29 struct edge{ 30 int y,next,v; 31 }e[MAXN<<1]; 32 int N; 33 namespace solution{ 34 inline void insert(int x,int y,int v){e[++len].next=LINK[x];LINK[x]=len;e[len].y=y;e[len].v=v;} 35 inline int gcd(int a,int b){return b==0?a:gcd(b,a%b);} 36 void init(){ 37 N=read(); 38 memset(vis,0,sizeof(vis)); 39 up(i,2,N){ 40 int x=read(),y=read(),v=read(); 41 insert(x,y,v); 42 insert(y,x,v); 43 } 44 } 45 void make_root(int node,int fa){ 46 max_siz[node]=0;siz[node]=1; 47 for(int i=LINK[node];i;i=e[i].next)if(!vis[e[i].y]&&e[i].y!=fa){ 48 make_root(e[i].y,node); 49 siz[node]+=siz[e[i].y]; 50 max_siz[node]=max(max_siz[node],siz[e[i].y]); 51 } 52 max_siz[node]=max(max_siz[node],sum-max_siz[node]); 53 if(max_siz[node]<max_siz[root])root=node; 54 } 55 void get_deep(int node,int fa){ 56 q[++tail]=dis[node]; 57 for(int i=LINK[node];i;i=e[i].next)if(e[i].y!=fa&&!vis[e[i].y]){ 58 dis[e[i].y]=dis[node]+e[i].v; 59 get_deep(e[i].y,node); 60 } 61 } 62 int col(int node,int dist){ 63 dis[node]=dist;head=1;tail=0; 64 get_deep(node,0); 65 cnt[0]=cnt[1]=cnt[2]=0; 66 up(i,head,tail)cnt[q[i]%3]++; 67 return cnt[0]*cnt[0]+2*cnt[1]*cnt[2]; 68 } 69 void work(int node){ 70 ans+=col(node,0); 71 vis[node]=1; 72 for(int i=LINK[node];i;i=e[i].next)if(!vis[e[i].y]){ 73 ans-=col(e[i].y,e[i].v); 74 root=0; 75 make_root(e[i].y,node); 76 work(root); 77 } 78 } 79 void slove(){ 80 sum=N;max_siz[0]=oo;root=0; 81 make_root(1,0); 82 work(root); 83 } 84 void output(){ 85 int d=gcd(ans,N*N); 86 printf("%d/%d\n",ans/d,N*N/d); 87 } 88 } 89 int main(){ 90 //freopen("input.in","r",stdin); 91 using namespace solution; 92 init(); 93 slove(); 94 output(); 95 return 0; 96 }
标签:
原文地址:http://www.cnblogs.com/Cydiater/p/5899646.html