Luo Gu P2634 [National Team] Cong Cong cocoa dotted rule

And compared to the previous template title, only need to change getdis this function can deal done this function is to determine the number of the condition is met when a parameter u as root. Here it is asked if the distance between two points is divisible by 3. Therefore, the number of direct discussions three cases just fine.

1, the path number divisible by 3 counts sum0

2, in addition to the path 31 than the number of counts by sum1

3, in addition to the path 32 than the number counted by sum2

The final answer is sum1 * sum2 + sum2 * sum1 + sum3 * sum3 / n * n then simplify what is the answer

#include<cstdio>
#include<cstdlib>
#include<iostream>
#include<cstring>
#include<cmath>
#include<algorithm>
#define maxn 20002
#define INF 2147483646
#define ll long long
using namespace std;
ll sum[3]; 
inline int gi()//输入挂 
{
  int date = 0,m = 1; char ch = 0;
  while(ch!='-'&&(ch<'0'||ch>'9'))ch = getchar();
  if(ch=='-'){m = -1; ch = getchar();}
  while(ch>='0' && ch<='9')
    {
      date = date*10+ch-'0';
      ch = getchar();
    }return date*m;
}
inline void write(ll qw) //输出挂 
{
  if(qw<0){putchar('-'); qw = -qw;}
  if(qw>9)write(qw/10);
  putchar(qw%10+'0');
}

struct node{int to,next,len;}t[2*maxn+5];
int head[maxn+5];
int sim[maxn+5],mxson[maxn+5];
bool vis[maxn+5];
intThe MX, the root, Summar; 
LL ANS; 
int n-, K, CNT, S; 

void addedge ( int U, int V, int L) // save FIG 
{ 
  CNT ++ ; 
  T [CNT] .to = V; 
  T [ CNT] .next = head [U]; 
  T [CNT] .LEN = L; 
  head [U] = CNT;
   return ; 
} 

void getRoot ( int U, int FA) // find the center of gravity function 
{ 
  SIM [U] = . 1 ; mxson [U] = 0;
   For ( int I = head [U]; I; I = T [I] .next) 
    { 
      int V = T [I] .to;
       IF (FA == || VIS V [V]) Continue ; 
      getRoot ( V, U); 
      SIM [U] = SIM [U] + SIM [V]; 
      mxson [U] = max (SIM [V], mxson [U]); 
    } 
  mxson [U] = max (mxson [U] , -S- SIM [U]);
   IF (mxson [U] <the MX) = U {the root; the MX = mxson [U];} 
} 

void getdis ( int U, int FA, int dist) // calculated plurality statistics in the case of subtrees satisfying the condition from the point u to go memory array to dis
{ 
  SUM [dist % . 3 ] ++ ;
   for ( int I = head [U]; I; I = T [I] .next) 
    { 
      int V = T [I] .to;
       IF (VIS [V] || FA == V) Continue ; 
      getdis (V, U, (dist + T [I] .LEN)% . 3 ); 
    } 
  return ; 
} 
LL GCD (A LL, LL B) { return B == 0 A: GCD? (B, a% B);}
 int consolate ( int STA, int LEN1) // calculate the number of the current situation satisfies the condition 
{ 
  SUM [ 0 ] = SUM [1] = sum[2] = 0;
  getdis(sta,0,len1);
  ll now = 2*sum[1]*sum[2] + sum[0]*(sum[0]-1) + sum[0];
  return now;
}

void Divide(int tr) //分治函数 
{
  ans = ans + consolate(tr,0);
  vis[tr] = true;
  for(int i = head[tr];i;i = t[i].next)
    {
      int v = t[i].to;
      if(vis[v])continue;
      ans = ans - consolate(v,t[i].len);
      S = sim[v]; root = 0;
      MX = INF; getroot(v,0);
      Divide(root);
    }
  return;
}

int main()
{
  int u,v,l;
      n = gi();
      cnt = 0; memset(head,0,sizeof(head));
      for(int i = 1; i <= n - 1; i ++)
    {
      u = gi(); v = gi(); l = gi();
      addedge(u,v,l); addedge(v,u,l);
    }
      ans = 0;
      memset(vis,0,sizeof(vis));
      MX = INF ; S = n; getroot(1,0);
      Divide(root);
      ll gyz=gcd(n*n,ans);
      write(ans/gyz);putchar('/');write(n*n/gyz);
  return 0;
}

 

Guess you like

Origin www.cnblogs.com/wsblm/p/11202610.html