topcoder srm 712 div1
problem1 link
将$a_{0},a_{1},...,a_{n-1}$看做$a_{0}x^{0}+a_{1}x^{1}+...+a_{n-1}x^{n-1}$。那么第一种操作相当于乘以$1+x$模$x^{n}-1$,第二种操作相当于乘以$1+x^{n-1}$模$x^{n}-1$。所以操作的顺序无关。所以只需要枚举两种操作各用了多少次即可
problem2 link
对于$m$个数字$x_{1},x_{2},..,x_{m}$来说,设$a=\frac{\sum_{i=1}^{m}x_{i}}{m}$,那么$\frac{1}{m}\sum_{i=1}^{m}(x_{i}-a)^{2}=\frac{1}{m}\left (\sum_{i=1}^{m}x_{i}^{2}-\frac{\left (\sum_{i=1}^{m}x_{i} \right )^{2}}{m^{2}} \right )$
所以,对于子树$T$,可以计算包含子树树根的大小为$m$的连通块有多少个,同时记录所有情况的$s_{1}=\sum_{i=1}^{m}x_{i}^{2},s_{2}=\left (\sum_{i=1}^{m}x_{i} \right )^{2}$之和。这样就是一个树上的动态规划。
problem3 link
首先,将所有的限制按照最近公共祖先分配到每个对应的结点上。那么现在就是每个子树有一些限制。
首先,分配结点以满足左右子树的限制。对于当前结点,枚举当前结点映射为最后的哪一个结点。
这时候对于限制,可以确定每个限制的$(x,y)$,$x$或者$y$:(1)一定在左侧;(2)一定在右侧;(3)都可以;(4)不是一定在左侧或者右侧但是$x$和$y$不能在一侧。第三类情况最后可以随意分配,比较简单。第四种情况暴力枚举$x$在左侧还是右侧。这样就可以确定所有的结点。
code for problem1
#include <algorithm>
#include <string>
#include <vector> class LR {
public:
std::string construct(const std::vector<long long> &s,
const std::vector<long long> &t) {
if (s == t) {
return "";
}
int n = static_cast<int>(s.size());
long long x0 = std::accumulate(s.begin(), s.end(), 0ll);
long long x1 = std::accumulate(t.begin(), t.end(), 0ll);
if (x0 == 0) {
return "No solution";
}
int k = 0;
while (x0 < x1) {
++k;
x0 <<= 1;
}
if (x0 != x1) {
return "No solution";
}
auto Check = [&](std::vector<long long> s, int x, int y) {
for (int i = 0; i < x; ++i) {
long long t = s[n - 1];
for (int i = n - 1; i > 0; --i) {
s[i] += s[i - 1];
}
s[0] += t;
}
for (int i = 0; i < y; ++i) {
long long t = s[0];
for (int i = 0; i < n - 1; ++i) {
s[i] += s[i + 1];
}
s[n - 1] += t;
}
return s == t;
};
for (int i = 0; i <= k; ++i) {
if (Check(s, i, k - i)) {
return std::string(i, 'L') + std::string(k - i, 'R');
}
}
return "No solution";
}
};
code for problem2
#include <vector> using BigDouble = __float128; class AverageVarianceSubtree {
struct Node {
BigDouble s1 = 0.0;
BigDouble s2 = 0.0;
BigDouble s3 = 0.0;
BigDouble number = 0; void Reset() {
s1 = s2 = s3 = 0.0;
number = 0;
} Node Merge(const Node &other) {
Node result;
result.s1 = s1 * other.number + other.s1 * number;
result.s2 = s2 * other.number + other.s2 * number + 2 * s3 * other.s3;
result.s3 = s3 * other.number + other.s3 * number;
result.number = number * other.number;
return std::move(result);
} void Add(const Node &other) {
s1 += other.s1;
s2 += other.s2;
s3 += other.s3;
number += other.number;
}
}; public:
double average(const std::vector<int> &p, const std::vector<int> &weight) {
n = static_cast<int>(p.size()) + 1;
tree.resize(n);
for (int i = 0; i < n - 1; ++i) {
tree[i + 1].push_back(p[i]);
tree[p[i]].push_back(i + 1);
}
this->weights = weight;
dp.resize(n);
for (int i = 0; i < n; ++i) {
dp[i].resize(n + 1);
}
BigDouble sum = 0;
BigDouble total = 0;
Dfs(0, -1);
for (int root = 0; root < n; ++root) {
for (int i = 1; i <= n; ++i) {
sum += (dp[root][i].s1 * i - dp[root][i].s2) / i / i;
total += dp[root][i].number;
}
}
return static_cast<double>(sum / total);
} private:
void Dfs(int u, int prev) {
long long w1 = weights[u];
long long w2 = w1 * w1;
dp[u][0].number = 1;
for (auto v : tree[u]) {
if (v == prev) {
continue;
}
Dfs(v, u);
std::vector<Node> f(n + 1);
for (int i = 0; i <= n; ++i) {
for (int j = 0; j <= n; ++j) {
if (i + j <= n) {
f[i + j].Add(dp[v][i].Merge(dp[u][j]));
}
}
}
dp[u] = std::move(f);
} for (int i = n - 1; i >= 0; --i) {
dp[u][i + 1].s1 = dp[u][i].s1 + dp[u][i].number * w2;
dp[u][i + 1].s2 =
dp[u][i].s2 + dp[u][i].number * w2 + 2 * w1 * dp[u][i].s3;
dp[u][i + 1].s3 = dp[u][i].s3 + dp[u][i].number * w1;
dp[u][i + 1].number = dp[u][i].number;
}
} std::vector<std::vector<int>> tree;
std::vector<int> weights;
std::vector<std::vector<Node>> dp;
int n = 0;
};
code for problem3
#include <unordered_set>
#include <vector> class BinaryTreeAndPermutation {
struct Node {
long long contain_ps = 0;
long long contain = 0;
long long used = 0;
int left = -1;
int right = -1;
int total = 0;
std::vector<std::pair<int, int>> constrains;
int n = 0; void Used(int t) { used |= 1ll << t; } void AddConstrain(int x, int y) {
for (const auto &e : constrains) {
if ((e.first == x && e.second == y) ||
(e.first == y && e.second == x)) {
return;
}
}
constrains.emplace_back(x, y);
} size_t UnUsedNodeNumber() const {
size_t num = 0;
for (int i = 0; i < n; ++i) {
if ((contain & (1ll << i)) != 0 && (used & (1ll << i)) == 0) {
++num;
}
}
return num;
} int UnUsedNode() const {
for (int i = 0; i < n; ++i) {
if ((contain & (1ll << i)) != 0 && (used & (1ll << i)) == 0) {
return i;
}
}
return -1;
} long long AllPs() const {
long long m = 0;
for (const auto &x : constrains) {
m |= 1ll << x.first;
m |= 1ll << x.second;
}
return m;
} bool Has(int x) const { return (contain_ps & (1ll << x)) != 0; }
}; public:
std::vector<int> findPermutation(const std::vector<int> &lef,
const std::vector<int> &rig,
const std::vector<int> &a,
const std::vector<int> &b,
const std::vector<int> &c) {
n = static_cast<int>(lef.size());
tree.resize(n);
for (int i = 0; i < n; ++i) {
tree[i].left = lef[i];
tree[i].right = rig[i];
tree[i].n = n;
}
for (size_t i = 0; i < a.size(); ++i) {
tree[c[i]].AddConstrain(a[i], b[i]);
}
result.resize(n, -1);
if (!Dfs(0)) {
return {};
}
for (int i = 0; i < n; ++i) {
if (result[i] == -1) {
result[i] = tree[0].UnUsedNode();
tree[0].Used(result[i]);
}
} return result;
} private:
bool Split(
const std::vector<std::pair<int, int>> &undecided,
std::vector<std::pair<std::unordered_set<int>, std::unordered_set<int>>>
*result) {
int m = static_cast<int>(undecided.size());
std::vector<bool> visited(m);
for (int i = 0; i < m; ++i) {
if (!visited[i]) {
result->emplace_back();
auto &curr = result->back();
curr.first.insert(undecided[i].first);
curr.second.insert(undecided[i].second);
while (true) {
bool updated = false;
for (int j = i + 1; j < m; ++j) {
if (!visited[j]) {
int x = undecided[j].first;
int y = undecided[j].second;
if ((curr.first.count(x) > 0 && curr.first.count(y)) > 0 ||
(curr.second.count(x) > 0 && curr.second.count(y) > 0)) {
return false;
}
if (curr.first.count(x) > 0 || curr.second.count(y) > 0) {
curr.first.insert(x);
curr.second.insert(y);
updated = true;
visited[j] = true;
} else if (curr.first.count(y) > 0 || curr.second.count(x) > 0) {
curr.first.insert(y);
curr.second.insert(x);
updated = true;
visited[j] = true;
}
}
}
if (!updated) {
break;
}
}
}
}
return true;
} bool Check(int root, int root_p) {
Node &node = tree[root];
Node &left = tree[node.left];
Node &right = tree[node.right];
if (root_p != -1 && ((left.contain_ps & (1ll << root_p)) != 0 ||
(right.contain_ps & (1ll << root_p)) != 0)) {
return false;
} std::unordered_set<int> must_left;
std::unordered_set<int> must_right;
std::unordered_set<int> root_pair;
std::vector<std::pair<int, int>> undecided;
for (const auto &x : node.constrains) {
if (x.first == root_p && x.second == root_p) {
continue;
}
if (x.first == root_p) {
if (!left.Has(x.second) && !right.Has(x.second)) {
root_pair.insert(x.second);
}
} else if (x.second == root_p) {
if (!left.Has(x.first) && !right.Has(x.first)) {
root_pair.insert(x.first);
}
} else if (left.Has(x.first) || right.Has(x.second)) {
if (!left.Has(x.first)) {
must_left.insert(x.first);
}
if (!right.Has(x.second)) {
must_right.insert(x.second);
}
} else if (left.Has(x.second) || right.Has(x.first)) {
if (!left.Has(x.second)) {
must_left.insert(x.second);
}
if (!right.Has(x.first)) {
must_right.insert(x.first);
}
} else {
undecided.push_back(x);
}
}
for (auto x : must_left) {
if (must_right.count(x) > 0) {
return false;
}
}
for (auto x : must_right) {
if (must_left.count(x) > 0) {
return false;
}
}
for (const auto &e : undecided) {
if (root_pair.count(e.first) > 0) {
root_pair.erase(e.first);
}
if (root_pair.count(e.second) > 0) {
root_pair.erase(e.second);
}
}
while (true) {
bool deleted = false;
for (size_t i = 0; i < undecided.size(); ++i) {
int x = undecided[i].first;
int y = undecided[i].second;
if ((must_left.count(x) > 0 && must_left.count(y) > 0) ||
(must_right.count(x) > 0 && must_right.count(y) > 0)) {
return false;
}
if ((must_left.count(x) > 0 && must_right.count(x) > 0) ||
(must_left.count(y) > 0 && must_right.count(y) > 0)) {
return false;
}
if (must_left.count(x) > 0 || must_right.count(y) > 0) {
must_left.insert(x);
must_right.insert(y);
deleted = true;
undecided.erase(undecided.begin() + i);
break;
} else if (must_left.count(y) > 0 || must_right.count(x) > 0) {
must_left.insert(y);
must_right.insert(x);
deleted = true;
undecided.erase(undecided.begin() + i);
break;
}
}
if (!deleted) {
break;
}
} for (int x : must_left) {
root_pair.erase(x);
}
for (int x : must_right) {
root_pair.erase(x);
}
if (tree[node.left].UnUsedNodeNumber() < must_left.size() ||
tree[node.right].UnUsedNodeNumber() < must_right.size()) {
return false;
}
std::vector<std::pair<std::unordered_set<int>, std::unordered_set<int>>>
splits;
if (!Split(undecided, &splits)) {
return false;
} size_t total = must_left.size() + must_right.size() + root_pair.size();
for (const auto &e : splits) {
total += e.first.size() + e.second.size();
}
if (static_cast<int>(total) > tree[root].total) {
return false;
}
int m = static_cast<int>(splits.size());
bool valid_assign = false;
for (int i = 0; i < (1 << m); ++i) {
size_t left_num = 0;
size_t right_num = 0;
for (int j = 0; j < m; ++j) {
size_t num1 = splits[j].first.size();
size_t num2 = splits[j].second.size();
if ((i & (1 << j)) == 0) {
left_num += num1;
right_num += num2;
} else {
left_num += num2;
right_num += num1;
}
}
if (left_num + must_left.size() <= tree[node.left].UnUsedNodeNumber() &&
right_num + must_right.size() <=
tree[node.right].UnUsedNodeNumber()) {
valid_assign = true;
for (int j = 0; j < m; ++j) {
if ((i & (1 << j)) == 0) {
must_left.insert(splits[j].first.begin(), splits[j].first.end());
must_right.insert(splits[j].second.begin(), splits[j].second.end());
} else {
must_right.insert(splits[j].first.begin(), splits[j].first.end());
must_left.insert(splits[j].second.begin(), splits[j].second.end());
}
}
break;
}
} if (!valid_assign) {
return false;
}
for (auto x : root_pair) {
if (tree[node.left].UnUsedNodeNumber() > must_left.size()) {
must_left.insert(x);
} else {
must_right.insert(x);
}
}
for (auto x : must_left) {
int t = tree[node.left].UnUsedNode();
result[x] = t;
tree[node.left].Used(t);
}
for (auto x : must_right) {
int t = tree[node.right].UnUsedNode();
result[x] = t;
tree[node.right].Used(t);
}
node.used = tree[node.left].used | tree[node.right].used;
if (root_p != -1) {
result[root_p] = root;
node.used |= 1ll << root;
}
node.contain =
tree[node.left].contain | tree[node.right].contain | 1ll << root;
return true;
} bool Dfs(int root) {
Node &node = tree[root];
if (node.left == -1) {
node.contain = 1ll << root;
node.total = 1;
if (!node.constrains.empty()) {
int p = node.constrains.front().first;
for (const auto &x : node.constrains) {
if (p != x.first || p != x.second) {
return false;
}
}
node.contain_ps = 1ll << p;
node.used = 1ll << root;
result[p] = root;
}
return true;
}
if (!Dfs(node.left) || !Dfs(node.right)) {
return false;
}
long long cur_ps = node.AllPs();
long long left_ps = tree[node.left].contain_ps;
long long right_ps = tree[node.right].contain_ps; node.contain_ps = cur_ps | left_ps | right_ps;
node.total = 1 + tree[node.left].total + tree[node.right].total; Node &left = tree[node.left];
Node &right = tree[node.right]; int root_p = -1;
for (const auto &x : node.constrains) {
if ((left.Has(x.first) && left.Has(x.second)) ||
(right.Has(x.first) && right.Has(x.second)) ||
(left.Has(x.first) && right.Has(x.first)) ||
(left.Has(x.second) && right.Has(x.second))) {
return false;
}
if (x.first == x.second) {
if (root_p != -1 && root_p != x.first) {
return false;
}
root_p = x.first;
}
} if (root_p != -1) {
return Check(root, root_p);
} else {
if (Check(root, -1)) {
return true;
}
for (int i = 0; i < n; ++i) {
if ((cur_ps & (1ll << i)) != 0 && Check(root, i)) {
return true;
}
}
return false;
}
} std::vector<int> result;
std::vector<Node> tree;
int n = 0;
};
topcoder srm 712 div1的更多相关文章
- Topcoder SRM 643 Div1 250<peter_pan>
Topcoder SRM 643 Div1 250 Problem 给一个整数N,再给一个vector<long long>v; N可以表示成若干个素数的乘积,N=p0*p1*p2*... ...
- Topcoder Srm 726 Div1 Hard
Topcoder Srm 726 Div1 Hard 解题思路: 问题可以看做一个二分图,左边一个点向右边一段区间连边,匹配了左边一个点就能获得对应的权值,最大化所得到的权值的和. 然后可以证明一个结 ...
- topcoder srm 714 div1
problem1 link 倒着想.每次添加一个右括号再添加一个左括号,直到还原.那么每次的右括号的选择范围为当前左括号后面的右括号减去后面已经使用的右括号. problem2 link 令$h(x) ...
- topcoder srm 738 div1 FindThePerfectTriangle(枚举)
Problem Statement You are given the ints perimeter and area. Your task is to find a triangle wi ...
- Topcoder SRM 602 div1题解
打卡- Easy(250pts): 题目大意:rating2200及以上和2200以下的颜色是不一样的(我就是属于那个颜色比较菜的),有个人初始rating为X,然后每一场比赛他的rating如果增加 ...
- Topcoder SRM 627 div1 HappyLettersDiv1 : 字符串
Problem Statement The Happy Letter game is played as follows: At the beginning, several players ...
- Topcoder SRM 584 DIV1 600
思路太繁琐了 ,实在不想解释了 代码: #include<iostream> #include<cstdio> #include<string> #include& ...
- TopCoder SRM 605 DIV1
604的题解还没有写出来呢.先上605的. 代码去practice房间找. 说思路. A: 贪心,对于每个类型的正值求和,如果没有正值就取最大值,按着求出的值排序,枚举选多少个类型. B: 很明显是d ...
- topcoder srm 575 div1
problem1 link 如果$k$是先手必胜那么$f(k)=1$否则$f(k)=0$ 通过对前面小的数字的计算可以发现:(1)$f(2k+1)=0$,(2)$f(2^{2k+1})=0$,(3)其 ...
随机推荐
- 安装FusionInsight
1.在华为平台上下载整体客户端,不建议下载单个组件客户端,后期关联测试还是要装上的. 2.下载后需要将服务器上的客户端拷贝到本地.打开xShell,新建会话,登陆本地虚拟机上的Linux系统(19 ...
- C# 如何批量修改集合元素的属性值?
我们往往会遇到要批量修改集合中元素的值,最笨的办法就是foreach循环,但本文介绍几种优雅的方法. 首先,我们准备好元素类和初始集合: 下面就是几种方法,目前并没有对性能做进一步的测试,有兴趣的童鞋 ...
- install scala & spark env
安装Scala 1,到http://www.scala-lang.org/download/ 下载与Spark版本对应的Scala.Spark1.2对应于Scala2.10的版本.这里下载scala- ...
- Unity之如何从fbx提取Animation clip文件
见代码: static void CreateAnim(string fbx, string target) { AnimationClip src = AssetDatabase.LoadAsset ...
- 并发工具CyclicBarrier
想想一下这样一个场景,有多个人需要过河,河上有一条船,船要等待满10个人才过河,过完河后每个人又各自行动. 这里的人相当于线程,注意这里,每个线程运行到一半的时候,它就要等待一个条件,即船满过河的条件 ...
- 参数化define
SV中的define,可以是对var类型,也可以是对function类型的,或者其他任何可以直接替换的字符. `define wordsize 8 应用 logic [1 :·wordsize] ...
- 1.安装Python3和PyCharm
一.安装Python3 1.进入官网:www.python.org 2.下载(可以选择你自己的电脑系统版本,我这里是win7 64位) 3.然后点击XXX.exe傻瓜式安装 4.配置环境变量 [右键计 ...
- html5-超级链接
<!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8&qu ...
- 一 django框架?
Django-1 一 什么是web框架? 框架,即framework,特指为解决一个开放性问题而设计的具有一定约束性的支撑结构,使用框架可以帮你快速开发特定的系统,简单地说,就是你用别人搭建好的舞 ...
- linux文件系统的用户和权限管理
1. 为什么要有用户的概念? 多用户,多任务业务对系统资源的隔离产生需求 2. linux 用户的分类? 2.1. 管理员 拥有操作所有文件的权限 2.2. 普通用户 2.2.1. 普通登录用户 2. ...