• P2634 [国家集训队]聪聪可可


    淀粉质

    第二道点分治的题

    关于点分治的一点理解:

    所谓点分治,其实就是把要求的问题(一般与路径有关)划分成两种情况

    1.路径经过rt(根节点)

    2.路径在根节点的子树内

    我们只需要处理情况1,因为情况2就是情况1的递归子问题

    在这个过程中,要注意容斥原理的应用;

    //--------------------------------------------------------------------------

    关于此题:

    w可预先%3(不会影响答案),注意乘法原理的应用;

      1 #include<cstdio>
      2 #include<cmath>
      3 #include<cstring>
      4 #include<algorithm>
      5 #include<iostream>
      6 using namespace std;
      7 #define up(i,l,r) for(register int i = (l); i <= (r); ++i)
      8 #define dn(i,l,r) for(register int i = (l); i >= (r); --i)
      9 #define ll long long
     10 #define re register
     11 using namespace std;
     12 
     13 template <typename T> void in(T &x) {
     14     x = 0; T f = 1; char ch = getchar();
     15     while(!isdigit(ch)) {if(ch == '-') f = -1; ch = getchar();}
     16     while( isdigit(ch)) {x = 10 * x + ch - 48; ch = getchar();}
     17     x *= f;
     18 }
     19 
     20 template <typename T> void out(T x) {
     21     if(x < 0) x = -x , putchar('-');
     22     if(x > 9) out(x/10);
     23     putchar(x%10 + 48);
     24 }
     25 //---------------------------------------------------------
     26 
     27 const int N = 20007;
     28 
     29 int n;
     30 ll ans = 0;
     31 
     32 struct edge {
     33     int v,w,nxt;
     34 }e[N<<1];int tot,head[N];
     35 
     36 void add(int u,int v,int w) {
     37     e[++tot].v = v;
     38     e[tot].w = w;
     39     e[tot].nxt = head[u];
     40     head[u] = tot;
     41 }
     42 
     43 //---------------------------------------------------------
     44 
     45 bool vis[N];
     46 int size[N],f[N];
     47 int Tsize,rt,dis[N];
     48 int t[3];
     49 
     50 void get_rt(int u,int fa) {
     51     size[u] = 1; f[u] = 0;
     52     for(re int i = head[u]; i ;i = e[i].nxt) {
     53         int v = e[i].v; if(v == fa || vis[v]) continue;
     54         get_rt(v,u); size[u] += size[v];
     55         f[u] = max(f[u],size[v]);
     56     }
     57     f[u] = max(f[u],Tsize-size[u]);
     58     if(f[u] < f[rt]) rt = u;
     59 }
     60 
     61 void get_dis(int u,int fa) {
     62     ++t[dis[u]%3];
     63     for(re int i = head[u]; i ;i = e[i].nxt) {
     64         int v = e[i].v; if(v == fa || vis[v]) continue;
     65         dis[v] = (dis[u]+e[i].w)%3; get_dis(v,u);
     66     }
     67 }
     68 
     69 ll calc(int u) {
     70     t[0] = t[1] = t[2] = 0;
     71     get_dis(u,0);
     72     return t[0]*t[0]+2*t[1]*t[2];
     73 }
     74 
     75 void solve(int u) {
     76     vis[u] = 1; dis[u] = 0;
     77     ans += calc(u);
     78     for(re int i = head[u]; i ;i = e[i].nxt) {
     79         int v = e[i].v; if(vis[v]) continue;
     80         dis[v] = e[i].w;
     81         ans -= calc(v);
     82         Tsize = size[v],rt = 0,f[0] = n+1;
     83         get_rt(v,0); solve(rt);
     84     }
     85 }
     86 
     87 void init() {
     88     memset(head,0,sizeof(head));
     89     memset(vis,0,sizeof(vis));
     90     ans = 0; Tsize = n,rt = 0,f[0] = n+1;
     91 }
     92 
     93 ll Gcd(ll a,ll b) {return b == 0 ? a:Gcd(b,a%b);}
     94 
     95 int main() {
     96     init();
     97     in(n); int x,y,w;
     98     up(i,1,n-1) {
     99         in(x); in(y); in(w); add(x,y,w%3),add(y,x,w%3);
    100         //技巧 mod 3 
    101     }
    102     get_rt(1,0); solve(rt);
    103     ll gcd = Gcd(ans,1ll*n*n);
    104     out(ans/gcd); putchar('/'); out(1ll*n*n/gcd);
    105     return 0;
    106 }
  • 相关阅读:
    网络知识
    DXP 技巧和龙芯3A装机
    312-金胜维 P系列2.5寸 480G SATA3 SSD固态硬盘
    NVIDIA Jetson TK1 开发板
    NVIDIA Jetson™ TX1
    XILINX FPGA 开发板 XC3S250E 核心板 学习板+12模块
    AES-OZ745 OZ745 Zynq-7000 开发板与套件
    北京太速科技——海外代购
    AR/VR增强现实 虚拟现实,嵌入式解决方案探讨
    270-VC709E 增强版 基于FMC接口的Xilinx Vertex-7 FPGA V7 XC7VX690T PCIeX8 接口卡
  • 原文地址:https://www.cnblogs.com/mzg1805/p/10737653.html
Copyright © 2020-2023  润新知