洛谷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. Git.之.最小化配置

    Git.之.最小化配置 做一个全局的用户配置,便于以后提交代码等,记录当前操作的用户. ## 添加配置 # git config [--local | --global | --system] use ...

  2. 2019.8.14 NOIP模拟测试21 反思总结

    模拟测试20的还没改完先咕着 各种细节问题=错失190pts T1大约三分钟搞出了式子,迅速码完,T2写了一半的时候怕最后被卡评测滚去交了,然后右端点没有初始化为n…但是这样还有80pts,而我后来还 ...

  3. windows无法启动MySQL服务报错1067的解决方法是怎样?

    方法一: 1.打开my.ini文件,找到default-storage-engine=InnoDB这一行,把它改成default-storage-engine=MyISAM.2.删除在MySQL安装目 ...

  4. 洛谷 P2955 [USACO09OCT]奇数偶数Even? Odd?【字符串/易错】

    题目描述 Bessie's cruel second grade teacher has assigned a list of N (1 <= N <= 100) positive int ...

  5. Python科学计算生态圈

  6. Tool-图片压缩-腾讯智图:腾讯智图

    ylbtech-Tool-图片压缩-腾讯智图:腾讯智图 智图是腾讯ISUX前端团队开发的一个专门用于图片压缩和图片格式转换的平台,其功能包括针对png,jpeg,gif等各类格式图片的压缩,以及为上传 ...

  7. mkdir、touch、rm和rmdir命令

    一.mkdir命令 mkdir命令用来创建目录.该命令创建由dirname命名的目录.如果在目录名的前面没有加任何路径名,则在当前目录下创建由dirname指定的目录:如果给出了一个已经存在的路径,将 ...

  8. 【JZOJ4762】【NOIP2016提高A组模拟9.7】千帆渡

    题目描述 输入 输出 样例输入 5 1 4 2 5 1 4 1 1 2 4 样例输出 2 1 4 数据范围 解法 设f[i][j]表示前 i个蓝色帆船中,选择了第 j个红色帆船作为结尾的最大答案. 那 ...

  9. 【JZOJ4813】【NOIP2016提高A组五校联考2】running

    题目描述 小胡同学是个热爱运动的好孩子. 每天晚上,小胡都会去操场上跑步,学校的操场可以看成一个由n 个格子排成的一个环形,格子按照顺时针顺序从0 到n-1 标号. 小胡观察到有m 个同学在跑步,最开 ...

  10. poj2449第K短路问题(A*算法)

    启发函数:f(x)=g(x)+h(x); g(x)表示初始点到x状态的代价,h(x)表示从x的状态到目标状态的代价的估计值(并不是真实的),实际最小代价<=h(x); 起点s,终点t,x.v=s ...