Codeforces 833D Red-black Cobweb【树分治】

简介: D. Red-black Cobweb time limit per test:6 seconds memory limit per test:256 megabytes input:standard input output:standard o...

D. Red-black Cobweb

time limit per test:6 seconds
memory limit per test:256 megabytes
input:standard input
output:standard output

Slastyona likes to watch life of nearby grove's dwellers. This time she watches a strange red-black spider sitting at the center of a huge cobweb.

The cobweb is a set of n nodes connected by threads, each of the treads is either red of black. Using these threads, the spider can move between nodes. No thread connects a node to itself, and between any two nodes there is a unique sequence of threads connecting them.

Slastyona decided to study some special qualities of the cobweb. She noticed that each of the threads has a value of clamminess x.

However, Slastyona is mostly interested in jelliness of the cobweb. Consider those of the shortest paths between each pair of nodes on which the numbers of red and black threads differ at most twice. For each such path compute the product of the clamminess of threads on the path.The jelliness of the cobweb is the product of all obtained values among all paths. Those paths that differ by direction only are counted only once.

Of course, this number can be huge, so Slastyona asks you to compute the jelliness of the given cobweb and print the answer modulo 109 + 7.

Input

The first line contains the number of nodes n (2 ≤ n ≤ 105).

The next n - 1 lines contain four integers each, denoting the i-th thread of the cobweb: the nodes it connects ui, vi(1 ≤ ui ≤ n, 1 ≤ vi ≤ n), the clamminess of the thread xi(1 ≤ x ≤ 109 + 6), and the color of the thread ci (). The red color is denoted by 0, and the black color is denoted by 1.

Output

Print single integer the jelliness of the cobweb modulo 109 + 7. If there are no paths such that the numbers of red and black threads differ at most twice, print 1.

Examples
Input
5
1 2 9 0
2 3 5 1
2 4 5 0
2 5 5 1
Output
1265625
Input
8
1 2 7 1
2 3 4 1
3 4 19 1
5 1 2 0
6 2 3 0
7 3 3 0
8 4 4 0
Output
452841614
Note

In the first example there are 4 pairs of nodes such that the numbers of threads of both colors on them differ at most twice. There pairs are (1, 3) with product of clamminess equal to 45, (1, 5) with product of clamminess equal to 45, (3, 4) with product of clamminess equal to 25 and (4, 5) with product of clamminess equal to 25. The jelliness of the cobweb is equal to 1265625.

题目链接:http://codeforces.com/contest/833/problem/D

官方题解:

下面给出AC代码:

  1 #include <cstdio>
  2 #include <cstring>
  3 #include <utility>
  4 #include <vector>
  5 
  6 const int N = 100000;
  7 const int MOD = (int)1e9 + 7;
  8 
  9 struct Edge { int v, x, c; };
 10 struct Sum { int c, p; };
 11 
 12 Sum& operator += (Sum& a, const Sum& b)
 13 {
 14     a.c += b.c;
 15     a.p = (long long)a.p * b.p % MOD;
 16 }
 17 
 18 int n, m, result, size[N], imbalance[N], w[2];
 19 bool resolved[N];
 20 Sum sum[N << 2];
 21 std::vector<int> vertices;
 22 std::vector<std::pair<int, int>> todos;
 23 std::vector<Edge> tree[N];
 24 
 25 int pow(int a, int n)
 26 {
 27     int result = 1;
 28     while (n) {
 29         if (n & 1) {
 30             result = (long long)result * a % MOD;
 31         }
 32         a = (long long)a * a % MOD;
 33         n >>= 1;
 34     }
 35     return result;
 36 }
 37 
 38 int prepare(int p, int u)
 39 {
 40     int size = 1;
 41     for (auto&& iterator : tree[u]) {
 42         auto v = iterator.v;
 43         if (v != p) {
 44             int s = prepare(u, v);
 45             result = (long long)result * pow(iterator.x, (long long)s * (n - s) % (MOD - 1)) % MOD;
 46             size += s;
 47         }
 48     }
 49     return size;
 50 }
 51 
 52 int prepare2(int p, int u)
 53 {
 54     vertices.push_back(u);
 55     size[u] = 1, imbalance[u] = 0;
 56     for (auto&& iterator : tree[u]) {
 57         auto&& v = iterator.v;
 58         if (v != p && !resolved[v]) {
 59             prepare2(u, v);
 60             size[u] += size[v];
 61             imbalance[u] = std::max(imbalance[u], size[v]);
 62         }
 63     }
 64 }
 65 
 66 void add(int k, const Sum& v)
 67 {
 68     for (; k < m << 2; k += ~k & k + 1) {
 69         sum[k] += v;
 70     }
 71 }
 72 
 73 void dfs(int p, int u, int offset, int product)
 74 {
 75     todos.emplace_back(offset, product);
 76     Sum s {0, 1};
 77     for (int k = offset - 1; k >= 0; k -= ~k & k + 1) {
 78         s += sum[k];
 79     }
 80     result = (long long)result * pow((long long)pow(product, s.c) * s.p % MOD, MOD - 2) % MOD;
 81     for (auto&& iterator : tree[u]) {
 82         auto&& v = iterator.v;
 83         if (v != p && !resolved[v]) {
 84             dfs(u, v, offset + w[iterator.c], (long long)product * iterator.x % MOD);
 85         }
 86     }
 87 }
 88 
 89 void divide(int root)
 90 {
 91     vertices.clear();
 92     prepare2(-1, root);
 93     m = size[root];
 94     for (auto&& u : vertices) {
 95         imbalance[u] = std::max(imbalance[u], m - size[u]);
 96     }
 97     for (auto&& u : vertices) {
 98         if (imbalance[u] < imbalance[root]) {
 99             root = u;
100         }
101     }
102     for (int t = 0; t < 2; ++ t) {
103         w[t] = 1, w[t ^ 1] = -2;
104         for (int i = 0; i < m << 2; ++ i) {
105             sum[i] = {0, 1};
106         }
107         add(m << 1, {1, 1});
108         for (auto&& iterator : tree[root]) {
109             auto&& v = iterator.v;
110             if (!resolved[v]) {
111                 dfs(root, v, (m << 1) + w[iterator.c], iterator.x);
112                 for (auto&& todo : todos) {
113                     add((m << 2) - todo.first, {1, todo.second});
114                 }
115                 todos.clear();
116             }
117         }
118     }
119     resolved[root] = true;
120     for (auto&& iterator : tree[root]) {
121         auto&& v = iterator.v;
122         if (!resolved[v]) {
123             divide(v);
124         }
125     }
126 }
127 
128 int main()
129 {
130 #ifdef LOCAL_JUDGE
131     freopen("D.in", "r", stdin);
132 #endif
133     while (scanf("%d", &n) == 1) {
134         for (int i = 0; i < n; ++ i) {
135             tree[i].clear();
136         }
137         for (int i = 0, a, b, x, c; i < n - 1; ++ i) {
138             scanf("%d%d%d%d", &a, &b, &x, &c);
139             a --;
140             b --;
141             tree[a].push_back({b, x, c});
142             tree[b].push_back({a, x, c});
143         }
144         result = 1;
145         prepare(-1, 0);
146         memset(resolved, 0, sizeof(*resolved) * n);
147         divide(0);
148         printf("%d\n", result);
149     }
150 }

 

目录
相关文章
|
13天前
|
存储 关系型数据库 分布式数据库
PostgreSQL 18 发布,快来 PolarDB 尝鲜!
PostgreSQL 18 发布,PolarDB for PostgreSQL 全面兼容。新版本支持异步I/O、UUIDv7、虚拟生成列、逻辑复制增强及OAuth认证,显著提升性能与安全。PolarDB-PG 18 支持存算分离架构,融合海量弹性存储与极致计算性能,搭配丰富插件生态,为企业提供高效、稳定、灵活的云数据库解决方案,助力企业数字化转型如虎添翼!
|
12天前
|
存储 人工智能 搜索推荐
终身学习型智能体
当前人工智能前沿研究的一个重要方向:构建能够自主学习、调用工具、积累经验的小型智能体(Agent)。 我们可以称这种系统为“终身学习型智能体”或“自适应认知代理”。它的设计理念就是: 不靠庞大的内置知识取胜,而是依靠高效的推理能力 + 动态获取知识的能力 + 经验积累机制。
393 135
|
12天前
|
存储 人工智能 Java
AI 超级智能体全栈项目阶段二:Prompt 优化技巧与学术分析 AI 应用开发实现上下文联系多轮对话
本文讲解 Prompt 基本概念与 10 个优化技巧,结合学术分析 AI 应用的需求分析、设计方案,介绍 Spring AI 中 ChatClient 及 Advisors 的使用。
496 132
AI 超级智能体全栈项目阶段二:Prompt 优化技巧与学术分析 AI 应用开发实现上下文联系多轮对话
|
2天前
|
人工智能 移动开发 自然语言处理
阿里云百炼产品月刊【2025年9月】
本月通义千问模型大升级,新增多模态、语音、视频生成等高性能模型,支持图文理解、端到端视频生成。官网改版上线全新体验中心,推出高代码应用与智能体多模态知识融合,RAG能力增强,助力企业高效部署AI应用。
207 0
|
12天前
|
人工智能 Java API
AI 超级智能体全栈项目阶段一:AI大模型概述、选型、项目初始化以及基于阿里云灵积模型 Qwen-Plus实现模型接入四种方式(SDK/HTTP/SpringAI/langchain4j)
本文介绍AI大模型的核心概念、分类及开发者学习路径,重点讲解如何选择与接入大模型。项目基于Spring Boot,使用阿里云灵积模型(Qwen-Plus),对比SDK、HTTP、Spring AI和LangChain4j四种接入方式,助力开发者高效构建AI应用。
502 122
AI 超级智能体全栈项目阶段一:AI大模型概述、选型、项目初始化以及基于阿里云灵积模型 Qwen-Plus实现模型接入四种方式(SDK/HTTP/SpringAI/langchain4j)
|
6天前
|
存储 JSON 安全
加密和解密函数的具体实现代码
加密和解密函数的具体实现代码
235 136
|
23天前
|
机器学习/深度学习 人工智能 前端开发
通义DeepResearch全面开源!同步分享可落地的高阶Agent构建方法论
通义研究团队开源发布通义 DeepResearch —— 首个在性能上可与 OpenAI DeepResearch 相媲美、并在多项权威基准测试中取得领先表现的全开源 Web Agent。
1585 87