洛谷P2634 [国家集训队]聪聪可可

静态点分治

一开始还以为要把分治树建出来……
• 树的结构不发生改变,点权边权都不变,那么我们利用刚刚的思路,有两种具体的分治方法。
• A:朴素做法,直接找重心,处理过重心的所有路径。然而,路径端点在同一子树(即路径实际上并不过重心)的情况会发生重复计数,需要使用类似容斥的方法,不断删去重复计数的部分。
• B:采用类似树形背包的思路,遍历子树时,只考虑当前子树和先前处理完的多颗子树之间的路径,以保证路径端点在不同的子树中,防止重复计数,不需要麻烦的容斥。在一些更为复杂的情况下,方法A不能解决问题,可以在方法B的基础上结合数据结构来解决。因此,方法B适用范围更广,细节更少不易错(个人观点),推荐大家使用。

感觉桶比较难以理解……容斥就是先更新整颗树的答案,然后处理lca是子树的答案。

#include<iostream>
#include<cstring>
#include<cstdio>
#define MAXN 20010
#define LL long long
#define INF 1000000000
using namespace std;
struct edge
{
int u,v,w,nxt;
#define u(x) ed[x].u
#define v(x) ed[x].v
#define w(x) ed[x].w
#define n(x) ed[x].nxt
}ed[MAXN*2];
int first[MAXN],num_e;
#define f(x) first[x]
int n;
int sum,mn,root;
int size[MAXN],mxsize[MAXN];
bool v[MAXN];
LL ans,cnt[3];
void getroot(int x,int fa)//找根节点
{
size[x]=1,mxsize[x]=0;
for(int i=f(x);i;i=n(i))
if(v(i)!=fa&&!v[v(i)])
{
getroot(v(i),x);
size[x]+=size[v(i)];
mxsize[x]=max(mxsize[x],size[v(i)]);
}
mxsize[x]=max(mxsize[x],sum-size[x]);
if(mxsize[x]<mn)mn=mxsize[x],root=x;
}
void ask(int x,int fa,int l)
{
cnt[l%3]++;
for(int i=f(x);i;i=n(i))
if(v(i)!=fa&&!v[v(i)])
ask(v(i),x,(l+w(i))%3);
}
int solve(int x,int add)
{
cnt[0]=cnt[1]=cnt[2]=0;
ask(x,0,add);
return 2ll*cnt[1]*cnt[2]+cnt[0]*cnt[0];
}
void divide(int x)
{
ans+=solve(x,0),v[x]=1;//更新答案
for(int i=f(x);i;i=n(i))
if(!v[v(i)])
{
ans-=solve(v(i),w(i));//容斥去重
sum=size[v(i)],mn=INF;
getroot(v(i),0);
divide(root);
}
}
int gcd(int a,int b){return !b?a:gcd(b,a%b);}
inline void add(int u,int v,int w);
inline int read()
{
int s=0;char a=getchar();
while(a<'0'||a>'9')a=getchar();
while(a>='0'&&a<='9'){s=s*10+a-'0',a=getchar();}
return s;
}
signed main()
{
cin>>n;
int u,v,w;
for(int i=1;i<n;i++)
{
u=read(),v=read(),w=read();
add(u,v,w%3);add(v,u,w%3);
}
sum=n;mn=INF;
getroot(1,0);
divide(root);
LL fm=n*n;
int GCD=gcd(ans,fm);
printf("%lld/%lld\n",ans/GCD,fm/GCD);
}
inline void add(int u,int v,int w)
{
++num_e;
u(num_e)=u;
v(num_e)=v;
w(num_e)=w;
n(num_e)=f(u);
f(u)=num_e;
}

模板—点分治A(容斥)(洛谷P2634 [国家集训队]聪聪可可)的更多相关文章

  1. 洛谷 P2634 [国家集训队]聪聪可可-树分治(点分治,容斥版) +读入挂+手动O2优化吸点氧才过。。。-树上路径为3的倍数的路径数量

    P2634 [国家集训队]聪聪可可 题目描述 聪聪和可可是兄弟俩,他们俩经常为了一些琐事打起来,例如家中只剩下最后一根冰棍而两人都想吃.两个人都想玩儿电脑(可是他们家只有一台电脑)……遇到这种问题,一 ...

  2. 洛谷P2634 [国家集训队]聪聪可可(点分治)

    传送门 题意: 给出一颗树,每条边都有一定的边权. 先问点之间路径和为\(3\)的倍数的点对有多少. 思路: 点分治模板题. 可以将问题转化为经过一个点\(t\)的路径和不经过点\(t\)的路径两种情 ...

  3. 洛谷P2634 [国家集训队]聪聪可可 (点分治)

    题目描述 聪聪和可可是兄弟俩,他们俩经常为了一些琐事打起来,例如家中只剩下最后一根冰棍而两人都想吃.两个人都想玩儿电脑(可是他们家只有一台电脑)……遇到这种问题,一般情况下石头剪刀布就好了,可是他们已 ...

  4. 洛谷-P2634 [国家集训队]聪聪可可 点分治

    Description 聪聪和可可是兄弟俩,他们俩经常为了一些琐事打起来,例如家中只剩下最后一根冰棍而两人都想吃.两个人都想玩儿电脑(可是他们家只有一台电脑)……遇到这种问题,一般情况下石头剪刀布就好 ...

  5. 洛谷P2634 [国家集训队]聪聪可可 点分治模板

    题意 在一棵树上任意选两个点,求它们距离模3为0的概率. 分析 树分治模板 Code #include<bits/stdc++.h> #define fi first #define se ...

  6. [洛谷P2634][国家集训队]聪聪可可

    题目大意:给你一棵树,随机选两个点,求它们之间路径长度是$3$的倍数的概率 题解:点分治,求出当前状态的重心,然后求出经过重心的答案,接着分治每棵子树.注意考虑重复计算的情况 卡点:无 C++ Cod ...

  7. 洛谷 P2634 [国家集训队]聪聪可可 解题报告

    P2634 [国家集训队]聪聪可可 题目描述 聪聪和可可是兄弟俩,他们俩经常为了一些琐事打起来,例如家中只剩下最后一根冰棍而两人都想吃.两个人都想玩儿电脑(可是他们家只有一台电脑)--遇到这种问题,一 ...

  8. 洛谷 P2634 [国家集训队]聪聪可可

    点分板子2333 注释都是错过的地方 #include<cstdio> #include<algorithm> using namespace std; typedef lon ...

  9. 洛谷P1501 [国家集训队]Tree II(LCT,Splay)

    洛谷题目传送门 关于LCT的其它问题可以参考一下我的LCT总结 一道LCT很好的练习放懒标记技巧的题目. 一开始看到又做加法又做乘法的时候我是有点mengbi的. 然后我想起了模板线段树2...... ...

随机推荐

  1. nfs网络共享服务基础

    nfs原理 1.开启RPC服务 2.NFS向RPC服务注册启动的端口 3.用户向RPC询问NFS服务的端口 4.RPC返回端口给客户端 5.客户端通过获得的端口与NFS服务器进行数据传输 实验步骤 一 ...

  2. Linux学习(一):软链接和硬链接

    今天起,决定开始自学Linux命令及Shell脚本,并用Linux学习(命令行,Shell及其他知识点)这一系列记录下自己的心路历程,内容不分先后,只记录自己觉得有必要的,简单的就不记了! 第一个知识 ...

  3. Java问题解读系列之基础相关---抽象类和接口

    今天来说一波自己对Java中抽象类和接口的理解,含参考内容: 一.抽象类 1.定义: public abstract class 类名{} Java语言中所有的对象都是用类来进行描述,但是并不是所有的 ...

  4. NOIP模拟 17.9.28

    公交车[问题描述]市内有

  5. Vue--过滤器(私有和公有)

    一.过滤器的基本使用 <!DOCTYPE html> <html lang="en"> <head> <meta charset=&quo ...

  6. 打印begin~end

    要求: 输入:begin和end 输出:依次打印出begin到end import java.util.Scanner; //递归打印begin —— end public class demo1 { ...

  7. Linux之软件包安装管理

    软件包分类: 源码包:脚本安装包(源C代码) 二进制包(rpm包,系统默认包) 源码包 1.源码包优点 开源,如果有足够的能力,完全可以修改源代码 可以自己选择所需要安装的功能 软件是编译安装,所以更 ...

  8. CMake学习笔记三

    添加子文件夹 ADD_SUBDIRECTORY(hello) ADD_SUBDIRECTORY(libs) ADD_SUBDIRECTORY(VSLIB) SET(IDE_TARGET_NAME VS ...

  9. Spring简介+HelloWorld

    IoC Container: 这是最重要的,也是最基础的, Spring的基础.它的作用是配置和Java对象的生命周期管理. DAO, ORM, AOP, WEB: 该模块可用于将工具或框架集成到了S ...

  10. 【转载】CPU相关总结

    What is the difference between Processor, Core, Logical Processor ? Processor : It’s the physical co ...