【CF833D】Red-Black Cobweb

题面

洛谷

题解

看到这种统计路径的题目当然是淀粉质啦。

考虑转化一下信息设一条路径上有红点\(a\)个,黑点\(b\)个

则\(2min(a,b)\geq max(a,b)\)

\(\Leftrightarrow 2*a\geq b\)且\(2*b\geq a\)

现在我们需要将过一个点的两条路径合并

设第一条为红\(a_1\),黑\(b_1\),第二条为红\(a_2\),黑\(b_2\)

则有

\[2(a_1+a_2)\geq b_1+b_2\\
2(b_1+b_2)\geq a_1+a_2
\]

将一个下标的放一边以便维护

\[2a_2-b_2\geq b_1-2a_1\\
2b_2-a_2\geq a_1-2b_1
\]

每次遍历完一颗子树,按时间加入所有的路径,将不等式左边看作查询二维平面,

右边看作插入坐标,就是一个\(cdq\)分治

复杂度是\(nlog^4\)(因为中间还有快速幂),但常数很小

代码

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <algorithm>
using namespace std;
inline int gi() {
register int data = 0, w = 1;
register char ch = 0;
while (!isdigit(ch) && ch != '-') ch = getchar();
if (ch == '-') w = -1, ch = getchar();
while (isdigit(ch)) data = 10 * data + ch - '0', ch = getchar();
return w * data;
}
const int MAX_N = 1e5 + 5;
const int Mod = 1e9 + 7;
int fpow(int x, int y) {
int res = 1;
while (y) {
if (y & 1) res = 1ll * res * x % Mod;
x = 1ll * x * x % Mod;
y >>= 1;
}
return res;
}
struct Point { int x, y, op, v; } ;
bool operator < (const Point &l, const Point &r) { return (l.x == r.x) ? (l.y < r.y) : (l.x < r.x); }
struct Graph { int to, cost, col, next; } e[MAX_N << 1]; int fir[MAX_N], e_cnt = 0;
void clearGraph() { memset(fir, -1, sizeof(fir)); e_cnt = 0; }
void Add_Edge(int u, int v, int w, int c) {
e[e_cnt].to = v, e[e_cnt].cost = w, e[e_cnt].col = c, e[e_cnt].next = fir[u];
fir[u] = e_cnt++;
}
int N, ans = 1, size[MAX_N];
bool used[MAX_N];
int centroid, sz, rmx, c1[MAX_N << 2], c2[MAX_N << 2];
Point stk[MAX_N], q[MAX_N << 2];
int top, cnt;
inline int lb(int x) { return x & -x; }
void add(int x, int v) { while (x <= N * 4 + 1) c1[x] = 1ll * c1[x] * v % Mod, c2[x]++, x += lb(x); }
int Sum(int x) { int res = 1; while (x > 0) res = 1ll * c1[x] * res % Mod, x -= lb(x); return res; }
int Cnt(int x) { int res = 0; while (x > 0) res += c2[x], x -= lb(x); return res; }
void Set(int x) { while (x <= N * 4 + 1) c1[x] = 1, c2[x] = 0, x += lb(x); }
void search_centroid(int x, int fa) {
size[x] = 1; int mx = 0;
for (int i = fir[x]; ~i; i = e[i].next) {
int v = e[i].to;
if (v == fa || used[v]) continue;
search_centroid(v, x);
size[x] += size[v];
mx = max(mx, size[v]);
}
mx = max(mx, sz - size[x]);
if (mx < rmx) rmx = mx, centroid = x;
}
void dfs(int x, int fa, int R, int B, int val) {
stk[++top] = (Point){R, B, 0, val};
for (int i = fir[x]; ~i; i = e[i].next) {
int v = e[i].to;
if (v == fa || used[v]) continue;
if (e[i].col == 0) dfs(v, x, R + 1, B, 1ll * val * e[i].cost % Mod);
else if (e[i].col != 0) dfs(v, x, R, B + 1, 1ll * val * e[i].cost % Mod);
}
}
void Div(int l, int r) {
if (l >= r) return ;
int mid = (l + r) >> 1;
Div(l, mid); Div(mid + 1, r);
int j = l;
for (int i = mid + 1; i <= r; i++) {
if (!q[i].op) continue;
while (q[j].x <= q[i].x && j <= mid) { if (!q[j].op) add(q[j].y, q[j].v); ++j; }
ans = 1ll * ans * Sum(q[i].y) % Mod * fpow(q[i].v, Cnt(q[i].y)) % Mod;
}
for (int i = l; i < j; i++) if (!q[i].op) Set(q[i].y);
inplace_merge(&q[l], &q[mid + 1], &q[r + 1]);
}
void solve(int x) {
used[x] = 1;
cnt = 0; int Pls = 2 * N + 1;
for (int i = fir[x]; ~i; i = e[i].next) {
int v = e[i].to;
if (used[v]) continue;
top = 0;
if (e[i].col == 0) dfs(v, x, 1, 0, e[i].cost);
else if (e[i].col == 1) dfs(v, x, 0, 1, e[i].cost);
for (int j = 1; j <= top; j++) {
int a = stk[j].x, b = stk[j].y;
q[++cnt] = (Point){2 * a - b + Pls, 2 * b - a + Pls, 1, stk[j].v};
}
for (int j = 1; j <= top; j++) {
int a = stk[j].x, b = stk[j].y;
q[++cnt] = (Point){b - 2 * a + Pls, a - 2 * b + Pls, 0, stk[j].v};
if (2 * min(a, b) >= max(a, b)) ans = 1ll * ans * stk[j].v % Mod;
}
}
Div(1, cnt);
for (int i = fir[x]; ~i; i = e[i].next) {
int v = e[i].to;
if (used[v]) continue;
sz = rmx = size[v];
search_centroid(v, x);
solve(centroid);
}
}
int main () {
clearGraph();
N = gi();
for (int i = 1; i < N; i++) {
int u = gi(), v = gi(), w = gi(), c = gi();
Add_Edge(u, v, w, c);
Add_Edge(v, u, w, c);
}
for (int i = 1; i <= 4 * N + 1; i++) c1[i] = 1, c2[i] = 0;
sz = rmx = N;
search_centroid(1, 0);
solve(centroid);
printf("%d\n", ans);
return 0;
}

【CF833D】Red-Black Cobweb的更多相关文章

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

    [CF833D]Red-Black Cobweb(点分治) 题面 CF 有一棵树,每条边有一个颜色(黑白)和一个权值,定义一条路径是好的,当且仅当这条路径上所有边的黑白颜色个数a,b满足2min(a, ...

  2. 【BZOJ1419】Red is good 期望

    [BZOJ1419]Red is good Description 桌面上有R张红牌和B张黑牌,随机打乱顺序后放在桌面上,开始一张一张地翻牌,翻到红牌得到1美元,黑牌则付出1美元.可以随时停止翻牌,在 ...

  3. 【BZOJ-1419】Red is good 概率期望DP

    1419: Red is good Time Limit: 10 Sec  Memory Limit: 64 MBSubmit: 660  Solved: 257[Submit][Status][Di ...

  4. 【BZOJ】【1419】Red is good

    数学期望/期望DP 还是戳<浅析竞赛中一类数学期望问题的解决方法>这篇论文…… $$ f[i][j]= \begin{cases} 0 &, &i==0 \\ f[i-1] ...

  5. 【BZOJ1419】 Red is good [期望DP]

    Red is good Time Limit: 10 Sec  Memory Limit: 64 MB[Submit][Status][Discuss] Description 桌面上有R张红牌和B张 ...

  6. 【BZOJ1419】Red is good 期望DP

    题目大意 桌面上有\(R\)张红牌和\(B\)张黑牌,随机打乱顺序后放在桌面上,开始一张一张地翻牌,翻到红牌得到\(1\)美元,黑牌则付出\(1\)美元.可以随时停止翻牌,在最优策略下平均能得到多少钱 ...

  7. 【cl】Red Hat Linux虚拟机安装Vmware Tools

    1.选择虚拟机,选中导航栏虚拟机>VMware Tool安装 选择右键>extract to 选择/home,新建了自己的文件夹,然后点击extract 一直enter,一直到 然后reb ...

  8. 【BZOJ】1419 Red is good

    [算法]期望DP [题解]其实把状态表示出来就是很简单的期望DP. f[i][j]表示i张红牌,j张黑牌的期望. i=0时,f[0][j]=0. j=0时,f[i][0]=i. f[i][j]=max ...

  9. 【jquery】基础知识

    jquery简介 1 jquery是什么 jquery由美国人John Resig创建,至今已吸引了来自世界各地的众多 javascript高手加入其team. jQuery是继prototype之后 ...

随机推荐

  1. POJ - 3476 A Game with Colored Balls---优先队列+链表(用数组模拟)

    题目链接: https://cn.vjudge.net/problem/POJ-3476 题目大意: 一串长度为N的彩球,编号为1-N,每个球的颜色为R,G,B,给出它们的颜色,然后进行如下操作: 每 ...

  2. Java虚拟机10:Client模式和Server模式的区别

    部分商用虚拟机中,Java程序最初是通过解释器对.class文件进行解释执行的,当虚拟机发现某个方法或代码块运行地特别频繁的时候,就会把这些代码认定为热点代码Hot Spot Code(这也是我们使用 ...

  3. 【[HNOI2010]弹飞绵羊】

    发现好像写了一个洛谷上最快的分块 这道题曾经一度感觉非常不可做,因为\(LCT\)的标签以及没有什么思路的分块 但是自从\(yy\)出来一个错误的哈希冲突分块之后(修改的时候挂掉了),就发现这道题不就 ...

  4. session.upload_progress.enabled开启的问题

    exp.php的内容,存在文件包含 <?php include($_GET['lfi']); $key = ini_get("session.upload_progress.prefi ...

  5. 复习静态页面polo-360

    1.ps快捷键 ctrl+1 恢复到100% ctrl+0 适应屏幕大小 ctrl+r 显示标尺 辅助线的利用 矩形框--图像--裁剪:文件存储为web所用格式,注意选格式. 1个像素的平铺 雪碧图的 ...

  6. SpringBoot实战(九)之Validator

    表单验证,是最为常见的,今天演示的是利用hibernate-validtor进行校验,有的时候,虽然前端方面通过jQuery或者require.js校验框架进行校验,可以减轻服务器的压力和改善用户体验 ...

  7. 阅读AuTO利用深度强化学习自动优化数据中心流量工程(一)

    目录 问题 解决方法 模型选择 框架构建 Sigcomm'18 AuTO: Scaling Deep Reinforcement Learning for Datacenter-Scale Autom ...

  8. 404 Note Found队-Alpha3

    目录 组员情况 组员1(组长):胡绪佩 组员2:胡青元 组员3:庄卉 组员4:家灿 组员5:凯琳 组员6:丹丹 组员7:家伟 组员8:政演 组员9:鸿杰 组员10:刘一好 组员11:何宇恒 展示组内最 ...

  9. ovs加dpdk出现EAL No free hugepages reported in hugepages-1048576kB

    问题 打开ovs的日志: cat /etc/local/var/log/openvswitch/ovs-vswichd.log 其中一条显示: 2018-07-30T02:12:05.443Z|000 ...

  10. version 1.5.2-04 of the jvm is not suitable for this product. version:1.6 or greater is required

    这里仅仅说明一个可能造成该问题的解决办法,也是我遇到的原因. 这句话的意思是说,eclipse须要至少1.6版本号或以上的JVM ,而你仅仅有1.5.2版本号的JVM.想想就认为非常奇怪,我装的但是J ...