problem1 link

最优的策略就是从最低下一层开始,每两层的三个节点的子树都可以用一次遍历覆盖。

problem2 link

从大到小依次放置每一种数字,并记录已经放置的数字一共有多少个$m$以及有多少个严格的升序列$K$。那个如果新放置的一个数字(必然小于序列中所有的数字)放在了升序列的开头,那么升序列个数不变;否则升序列的个数增加1.所以有$K$个位置可以使得升序列个数不变,而有$n+1-K$个位置使得升序列个数增加1.现在考虑新放置的数字有多个的情况。假设新放置的数字有$n$个,首先将他们插入到原来的序列前现将其分为$t$组,要求每一组插入的时候是连续的。那么每一组中前面的数字必定是有几个就会使得升序列个数增加几个,即一定至少增加$n-t$.那么如果$t$组中选择$x$组放在之前增序列的开头,剩下的$t-x$组放在其他位置,那么增加的增序列的总个数为$(n-t)+(t-x)$,方案数为$C_{K}^{x}C_{m+1-K}^{t-x}$.

problem3 link

首先将边上的$4m$个点按照顺时针看作一个序列,那么对于序列中的每个点$i$可以计算一个$left[i],right[i]$。$left[i]$表示在$i$前面最远的点满足那个点与$i$点的连线使得所有内部的点都在这条线上或者右侧。$right[i]$含义类似。

现在枚举每个点作为$a$作为三角形的一个顶点,其他两个顶点设为$b,c$。那么$b,c$一定要满足$left[a]\leq c\leq right[b],left[c]\leq b\leq right[a]$.

所以如果$b$也一旦确定,那么$c$的可选个数为$right[b]-left[a]+1$,所以当$a$确定时的答案为$f(a)=\sum_{b=left[left[a]]}^{right[a]}right[b]-left[a]+1$

特殊情况是如果$left[left[a]]$跟 $a$是同一个点的时候,这时候$b$的取值是$[a+1, right[a]]$,即便这样$f(a)=\sum_{b=a+1}^{right[a]}right[b]-left[a]+1$还是多算了两个不合法的三角形,它们是 $(a,left[a],left[a])$以及$(a,left[a],a)$

code for problem1

#include <stdint.h>

class TrafficCongestion {
static constexpr int kMod = 1000000007; public:
int theMinCars(int treeHeight) {
int result = 0;
while (treeHeight >= 0) {
if (treeHeight <= 1) {
result = (result + 1) % kMod;
break;
} else {
result += Pow(treeHeight - 1);
result %= kMod;
treeHeight -= 2;
}
}
return result;
} private:
static int Pow(int k) {
int64_t result = 1;
int64_t a = 2;
while (k > 0) {
if ((k & 1) == 1) {
result = result * a % kMod;
}
a = a * a % kMod;
k >>= 1;
}
return static_cast<int>(result);
}
};

code for problem2

#include <stdint.h>
#include <cstring>
#include <vector> class LISNumber {
static constexpr int64_t kMod = 1000000007;
static constexpr int64_t kMax = 36; public:
int count(const std::vector<int> &cards, int K) {
if (K < cards.back()) {
return 0;
}
int N = 0;
for (auto e : cards) {
N += e;
}
if (K > N) {
return 0;
} Initialize(); std::vector<int> f0(K + 1, 0);
std::vector<int> f1(K + 1, 0);
f0[cards.back()] = 1;
int m = cards.back();
for (int i = static_cast<int>(cards.size()) - 2; i >= 0; --i) {
int n = cards[i];
for (auto &e : f1) {
e = 0;
}
for (int k = 1; k <= K; ++k) {
if (f0[k] == 0) {
continue;
}
for (int t = 1; t <= n; ++t) {
auto b = static_cast<int64_t>(f0[k]) * split_[n][t] % kMod;
int delta_k = n - t;
for (int x = 0; x <= t && x + delta_k + k <= K; ++x) {
int b1 = static_cast<int>(b * c_[k][t - x] % kMod *
c_[m - k + 1][x] % kMod);
(f1[x + delta_k + k] += b1) %= kMod;
}
}
}
m += n;
f0 = f1;
}
return f0[K];
} private:
void Initialize() {
c_[0][0] = 1;
for (int i = 1; i <= kMax; ++i) {
c_[0][i] = 0;
}
for (int i = 1, end = kMax * kMax; i <= end; ++i) {
c_[i][0] = 1;
for (int j = 1; j <= kMax; ++j) {
c_[i][j] = (c_[i - 1][j] + c_[i - 1][j - 1]) % kMod;
}
}
memset(split_, 0, sizeof(split_));
std::vector<std::pair<int, int>> p;
for (int i = 1; i <= kMax; ++i) {
p.push_back({i, 1});
Dfs(1, i, i, &p);
p.clear();
}
} void Dfs(int depth, int begin, int sum, std::vector<std::pair<int, int>> *p) {
if (sum > kMax) {
return;
}
{
int64_t x = 1;
int n = depth;
for (size_t i = 0; i < p->size(); ++i) {
(x *= c_[n][(*p)[i].second]) %= kMod;
n -= (*p)[i].second;
}
(split_[sum][depth] += static_cast<int>(x)) %= kMod;
}
for (int i = begin, end = kMax - sum; i <= end; ++i) {
if (p->back().first == i) {
p->back().second += 1;
} else {
p->push_back({i, 1});
}
Dfs(depth + 1, i, sum + i, p); if (p->back().second > 1) {
p->back().second -= 1;
} else {
p->pop_back();
}
}
} int c_[kMax * kMax + 1][kMax + 1];
int split_[kMax + 1][kMax + 1];
};

code for problem3

#include <unistd.h>
#include <algorithm>
#include <vector> class EnclosingTriangle {
public:
long long getNumber(int m, const std::vector<int>& x,
const std::vector<int>& y) {
const int n = m << 2;
std::vector<std::pair<int, int>> all(3 * n);
std::vector<int> left(3 * n);
std::vector<int> right(3 * n);
std::vector<long long> prefix(3 * n);
{
int idx = 0;
auto Add = [&](int x0, int y0, int x1, int y1) {
int dx = x1 >= x0 ? 1 : -1;
int dy = y1 >= y0 ? 1 : -1;
int x_num = abs(x1 - x0) + 1;
int y_num = abs(y1 - y0) + 1;
for (int i = 0; i < x_num; ++i) {
for (int j = 0; j < y_num; ++j) {
all[idx] = all[idx + n] = all[idx + n + n] =
std::make_pair(i * dx + x0, j * dy + y0);
++idx;
}
}
};
Add(0, 0, 0, m - 1);
Add(0, m, m - 1, m);
Add(m, m, m, 1);
Add(m, 0, 1, 0);
}
{
auto Check = [&](const std::pair<int, int>& p1,
const std::pair<int, int>& p2) {
long long dx1 = p2.first - p1.first;
long long dy1 = p2.second - p1.second;
for (size_t i = 0; i < x.size(); ++i) {
int dx2 = x[i] - p1.first;
int dy2 = y[i] - p1.second;
if (dx1 * dy2 - dy1 * dx2 > 0) {
return false;
}
}
return true;
};
for (int i = n; i < n + n; ++i) {
{
int low = i - n + 1;
int up = i - 1;
int result = up;
while (low <= up) {
int mid = (low + up) >> 1;
if (Check(all[mid], all[i])) {
result = std::min(result, mid);
up = mid - 1;
} else {
low = mid + 1;
}
}
left[i - n] = left[i] = left[i + n] = i - result;
}
{
int low = i + 1;
int up = i + n - 1;
int result = low;
while (low <= up) {
int mid = (low + up) >> 1;
if (Check(all[i], all[mid])) {
result = std::max(result, mid);
low = mid + 1;
} else {
up = mid - 1;
}
}
right[i - n] = right[i] = right[i + n] = result - i;
}
}
prefix[0] = right[0];
for (int i = 1; i < n + n + n; ++i) {
prefix[i] = prefix[i - 1] + right[i];
}
}
long long result = 0;
for (int a = n; a < n + n; ++a) {
int c = a - left[a];
int b_left = std::max(c - left[c] + n, a + 1);
int b_right = a + right[a];
if (b_right < b_left) {
continue;
}
result += prefix[b_right] - prefix[b_left - 1];
result -= static_cast<long long>(b_right - b_left + 1) *
(c + n - b_left - 1 + c + n - b_right - 1) / 2;
if (c + n == b_right) {
// (a, c, c) and (a, c, a) are invalid.
result -= 2;
}
}
return result / 3;
}
};

  

topcoder srm 585 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. SRM 585 DIV1 L2

    记录dp(i, j)表示前i种卡片的排列,使得LISNumber为j的方法数. #include <iostream> #include <vector> #include & ...

随机推荐

  1. plsql中文乱码

    一.关于PLSQL无法正确显示中文 刚才下载安装了PLSQL Developer 9.0.0.1601 汉化绿色版,执行SQL查询语句,发现显示的数据中只要有中文都会以?表示. 原因:客户端跟服务器的 ...

  2. 做二级菜单时候遇到的关于事件冒泡以及mouseover和mouseenter的不同

    二级菜单作为最普通小组件,我遇到了坑. <style> .wrapper { height: 150px; border: 1px solid; width: 150px; } .wrap ...

  3. SpringBoot定时任务说明

    1. 定时任务实现方式 定时任务实现方式: Java自带的java.util.Timer类,这个类允许你调度一个java.util.TimerTask任务.使用这种方式可以让你的程序按照某一个频度执行 ...

  4. 做一个vue的todolist列表

    <template> <div id="app"> <input type="text" v-model="todo&q ...

  5. python-获取当前工作路径

    1.sys.argv[0] import sys print sys.argv[0]#获得的是当前执行脚本的位置(若在命令行执行的该命令,则为空) 运行结果(在python脚本中执行的结果): F:/ ...

  6. sql中遍历字符串

    在sql或者存储过程中会需要遍历字符串. ), --如111,222,333,尾部加, ), @Id int, ) set @split = ',' ) begin ,) ,charindex(@sp ...

  7. 6、LwIP协议规范翻译——缓冲及内存管理

    6.缓冲及内存管理 在一个通信系统中,内存缓冲管理系统必须容纳各种大小的缓冲数据,其范围从包含具有数百个字节的数据的全尺寸TCP段到只有几个字节的短ICMP回复包.此外,为了避免拷贝,应该让数据内容缓 ...

  8. .net core 获取不到session 和cookies的值

    在启动类的configure services()方法中,设置选项.checkconsent必需=context=false;如下: services.Configure<CookiePolic ...

  9. jQuery Mobile的默认配置项具体解释,jQuery Mobile的中文配置api,jQuery Mobile的配置说明,配置大全

    版权声明:本文为博主原创文章,未经博主同意不得转载. https://blog.csdn.net/xmt1139057136/article/details/35258199 学习jQuery Mob ...

  10. 合作开发工具——freeze和pipreqs

    以后在合作开发的过程中,难免会用到别人开发到一半或者将自己开发的项目交给别人,在转交项目的时候需要让别人知道本项目中用到了哪些模块,这时可以用到一条命令来帮助我们. pip3 freeze # 获取环 ...