【CF833D】Red-Black Cobweb(点分治)

题面

CF

有一棵树,每条边有一个颜色(黑白)和一个权值,定义一条路径是好的,当且仅当这条路径上所有边的黑白颜色个数a,b满足2min(a,b)>=max(a,b),一条路径的权值为路径上所有边的权值的乘积,求所有好的路径的权值乘积.
\(n<=10^5\)

题解

首先看到求所有路径相关的内容,不难想到点分治。
两个限制可以转化为需要同时满足:\(2a\ge b,2b\ge a\)。
对于两条路径\(a1,b1/a2,b2\)考虑如何合并。
需要满足的两个条件就变成了\(2(a1+a2)\ge b1+b2\)以及\(2(b1+b2)\ge a1+a2\)
再稍微拆开看看就变成了\(2a1-b1\ge b2-2a2\),另一个类似。
这里怎么计算总的方案数,那么就用总数减去不合法的,如果不合法显然只会有一个不等式不合法(因为另外一个不等式是由最大值的两倍大于较小值得到的,它无论如何都会是对的),那么只需要统计有一个不合法的所有链就好了。

#include<iostream>
#include<cstdio>
using namespace std;
#define MAX 100100
#define MOD 1000000007
inline int read()
{int x=0;bool t=false;char ch=getchar();while((ch<'0'||ch>'9')&&ch!='-')ch=getchar();if(ch=='-')t=true,ch=getchar();while(ch<='9'&&ch>='0')x=x*10+ch-48,ch=getchar();return t?-x:x;
}
int fpow(int a,int b){int s=1;while(b){if(b&1)s=1ll*s*a%MOD;a=1ll*a*a%MOD;b>>=1;}return s;}
struct Line{int v,next,w,c;}e[MAX<<1];
int h[MAX],cnt=1;
inline void Add(int u,int v,int w,int c){e[cnt]=(Line){v,h[u],w,c};h[u]=cnt++;}
int Size,mx,rt,size[MAX];bool vis[MAX];
int n,N,ans,ans1=1,ans2=1;
int lb(int x){return x&(-x);}
struct BIT
{int c1[MAX<<3],c2[MAX<<3];void pre(){for(int i=1;i<=N;++i)c1[i]=1,c2[i]=0;}void Modify(int x,int w){while(x<=N)c1[x]=1ll*c1[x]*w%MOD,c2[x]+=1,x+=lb(x);}void Clear(int x){while(x<=N)c1[x]=1,c2[x]=0,x+=lb(x);}int Querys(int x){int s=1;while(x)s=1ll*s*c1[x]%MOD,x-=lb(x);return s;}int Queryt(int x){int s=0;while(x)s+=c2[x],x-=lb(x);return s;}int Querys(int l,int r){return 1ll*Querys(r)*fpow(Querys(l-1),MOD-2)%MOD;}int Queryt(int l,int r){return Queryt(r)-Queryt(l-1);}
}c1,c2;
void Getroot(int u,int ff)
{int ret=0;size[u]=1;for(int i=h[u];i;i=e[i].next){int v=e[i].v;if(v==ff||vis[v])continue;Getroot(v,u);size[u]+=size[v];ret=max(ret,size[v]);}ret=max(ret,Size-size[u]);if(ret<mx)mx=ret,rt=u;
}
struct Pair{int a,b,w;}S[MAX],T[MAX];
int top,sum,W,SW,py;
void dfs(int u,int ff,int a,int b,int w)
{T[++top]=(Pair){a,b,w};W=1ll*w*W%MOD;for(int i=h[u];i;i=e[i].next)if(e[i].v!=ff&&!vis[e[i].v])dfs(e[i].v,u,a+(e[i].c^1),b+e[i].c,1ll*w*e[i].w%MOD);
}
void Divide(int u)
{vis[u]=true;sum=0;SW=1;S[++sum]=(Pair){0,0,1};c1.Modify(py,1);c2.Modify(py,1);for(int i=h[u];i;i=e[i].next){int v=e[i].v;if(vis[v])continue;top=0;W=1;dfs(e[i].v,u,e[i].c^1,e[i].c,e[i].w);ans1=1ll*ans1*fpow(W,sum)%MOD*fpow(SW,top)%MOD;SW=1ll*SW*W%MOD;for(int j=1;j<=top;++j){int A=T[j].b-2*T[j].a-1+py,B=T[j].a-2*T[j].b-1+py;ans2=1ll*ans2*c1.Querys(2,A)%MOD*fpow(T[j].w,c1.Queryt(2,A))%MOD;ans2=1ll*ans2*c2.Querys(2,B)%MOD*fpow(T[j].w,c2.Queryt(2,B))%MOD;}for(int j=1;j<=top;++j){int A=2*T[j].a-T[j].b+py;c1.Modify(A,T[j].w);int B=2*T[j].b-T[j].a+py;c2.Modify(B,T[j].w);S[++sum]=T[j];}}for(int j=1;j<=sum;++j){int A=2*S[j].a-S[j].b+py;c1.Clear(A);int B=2*S[j].b-S[j].a+py;c2.Clear(B);}for(int i=h[u];i;i=e[i].next){int v=e[i].v;if(vis[v])continue;Size=mx=size[v];Getroot(v,u);Divide(rt);}
}
int main()
{n=read();py=n+n+2;N=5*n;c1.pre();c2.pre();for(int i=1,u,v,w,c;i<n;++i)u=read(),v=read(),w=read(),c=read(),Add(u,v,w,c),Add(v,u,w,c);Size=mx=n;Getroot(1,0);Divide(rt);ans=1ll*ans1*fpow(ans2,MOD-2)%MOD;printf("%d\n",ans);return 0;
}

转载于:https://www.cnblogs.com/cjyyb/p/10496657.html

【CF833D】Red-Black Cobweb(点分治)相关推荐

  1. 【CF833D】Red-Black Cobweb

    [CF833D]Red-Black Cobweb 题面 洛谷 题解 看到这种统计路径的题目当然是淀粉质啦. 考虑转化一下信息设一条路径上有红点\(a\)个,黑点\(b\)个 则\(2min(a,b)\ ...

  2. CF833D Red-Black Cobweb 点分治、树状数组

    传送门 统计所有路径的边权乘积的乘积,不难想到点分治求解. 边权颜色比例在\([\frac{1}{2},2]\)之间,等价于\(2B \geq R , 2R \geq B\)(\(R,B\)表示红色和 ...

  3. Codeforces 833D Red-Black Cobweb 边分治

    题意 一颗树,有边权,和颜色(红或黑) 求,所有的路径中,满足两种颜色的个数差不超过少的颜色的两倍的路径的权值的乘积 路径的权值为经过的边的权值的乘积 题解 边分治牛逼!!! 出现了两个错误,一个是, ...

  4. Codeforces 833D Red-Black Cobweb [点分治]

    洛谷 Codeforces 思路 看到树上路径的统计,容易想到点分治. 虽然只有一个限制,但这个限制比较麻烦,我们把它拆成两个. 设黑边有\(a\)条,白边有\(b\)条,那么有 \[ 2a\geq ...

  5. CF833D Red-Black Cobweb

    题面 题解 点分治大火题... 设白边数量为$a$,黑边为$b$,则$2min(a,b)\geq max(a,b)$ 即$2a\geq b\;\&\&2b\geq a$ 考虑点分治时如 ...

  6. P4062 [Code+#1]Yazid 的新生舞会(区间绝对众数+分治/树状数组维护高维前缀和)

    P4062 [Code+#1]Yazid 的新生舞会 杭电多校懂得都懂 Code1 分治 比较喜欢分治的做法,非常好写.skylee大佬题解 首先对于任何一个区间来说,由于两个端点不确定性非常难以一次 ...

  7. [XSY] 树与图(树形DP、生成函数、分治NTT、重链剖分)

    树与图 如果真的在图上跑算法,那么光建图复杂度就O(n2logn)O(n^2logn)O(n2logn)了,这显然不可行.所以一定要把 在图上的操作 转换成 在树上的操作 在图上删去点u,相当于在树上 ...

  8. P4169 [Violet]天使玩偶/SJY摆棋子 [CDQ分治]

    天使玩偶天使玩偶天使玩偶 Ayu 在七年前曾经收到过一个天使玩偶,当时她把它当作时间囊埋在了地下.而七年后 的今天,Ayu 却忘了她把天使玩偶埋在了哪里,所以她决定仅凭一点模糊的记忆来寻找它. 我们把 ...

  9. 【楼天城男人八题】【树分治|Treap+启发式合并】POJ1741 Tree

    题面在这里 待我先膜拜一下楼教主-- 首先这题是很明显的树分治 想说点什么却发现已经没什么好说了 然后我们来看另一种解法:平衡树乱搞 这里用的是Treap实现 对于每个节点,用Treap记录该子树每个 ...

最新文章

  1. [CVPR 2020] RandLA-Net:大场景三维点云语义分割新框架(已开源)
  2. SQL入门经典(第5版)学习笔记(三)
  3. ThreadPoolExecutor(上篇)
  4. python一点基础都没有的怎么办-Python基础常见问题总结(一)
  5. IIS网站服务器性能优化指南
  6. Linux学习记录-11
  7. Portainer简介及部署
  8. Win32下显示、隐式加载DLL的方法
  9. storm throw 口袋妖怪_pokemon go游戏术语都有哪些 口袋妖怪go玩法术语攻略
  10. 史上最详细的AVL树(含代码实现)
  11. [nltk_data] Error loading words: <urlopen error [Errno 11004]
  12. 如何关闭打开文件安全警告
  13. 在电脑上剪辑视频用什么软件 如何在电脑上剪辑视频
  14. 襄州区张家集镇社工站参与重点人群“敲门行动”
  15. 什么是蜘蛛池的搜索留痕技术
  16. 计算机高级技师证怎么考?
  17. 聚焦场景化应用 华为要做数字化转型的“赶路人”
  18. 伊朗太阳能光伏市场:易建钱难筹
  19. 如何驯服野生论文 | EndNote
  20. 数字射线检测图像质量

热门文章

  1. 只有他自己知道——生活所迫罢了
  2. Android实现直播的博文和流程(全过程,超详细/附源码)
  3. 如何在头条做好影视解说自媒体?
  4. ES6常问面试题(Promise,async和await 等)
  5. (个人笔记) java 打印不了韩文,乌龙事件
  6. 出栈顺序(栈和队列)B
  7. ParaView绘制自由水面的等值线图
  8. 选择合适的垃圾收集器
  9. PS系列 -- 颜色替换
  10. 自定义竖向SeekBar (VerticalSeekBar)