topcoder srm 545 div1
problem1 link
这个可以贪心地从前向后构造。假设当前已经的字符串为$S$,对于一个字符$c$来说,设将$c$加到$S$后得到的新串为$S^{'}$。那么如果$X+Y+Z \ge minInv$,那么这个之后的构造就是有解的。其中$X$表示$S^{'}$中逆序对个数;$Y$表示剩下的字符与$S^{'}$中的字符构成的逆序对的个数;$Z$表示剩下的字符能构成的最大逆序对个数(从大到小排列即可)。
problem2 link
首先处理掉垂直发射的情况。剩下的就是不垂直的。直接枚举直线的斜率,即$(x, y)$且$x,y$ 互质。由于斜率为正以及为负是对称的,所以只考虑为正的情况。对于指定的斜率,一共可以画出$L+1$条线。这些线分为两部分,第一部分从矩形的上边出去;第二部分从矩形的右侧出去。对于第一部分,直线经过的格点的数目是确定的,所以只要统计有多少条即可。
对于第二部分,起点越靠后,经过的格点数越少,它的规律是每$x$个经过的格点减少1.即假设从$(t,0)$出发的直线且从右侧出去时经过的格点是$p$,那么从$(t+x,0)$出发的直线经过的格点一定是$p-1$.假设$L=20,H=14,x=3,y=1$,那么从$(0,0),(1,0),(2,0)$出发的直线经过7个格点,从$(3,0),(4,0),(5,0)$出发的直线经过6个,依次类推,所以答案为$x*\sum_{i=K}^{7}C_{i}^{K}=x*\sum_{i=1}^{7}C_{i}^{K}=x*C_{8}^{K+1}$
problem3 link
每个数字最多有20位,所以只需要考虑20位即可。
对于某一位来说,如果所有数字在这个位上全是1或者全是0,那么不需要考虑这一位。那么现在只需要考虑那么既有0又有1的位。一个分配的原则就是在某一位上所有为0的数字不能分配到一个颜色。
考虑容斥原理。所有的情况有$2^n$种。减去在某一位上出现冲突而在其他位任意的情况(即这一位的所有的0都染成同一个颜色),这时候两个位同时冲突的情况就会多减了一次,所以再加上同时在两位上有冲突而其他位任意的情况。依次类推下去。
code for problem1
#include <string>
#include <vector>
using namespace std; class StrIIRec {
public:
string recovstr(int n, int minInv, string minStr) {
if (n == 1) {
return minStr;
}
while (static_cast<int>(minStr.size()) < n) {
minStr += 'a';
}
std::string s = "";
bool equal = true;
int mask = (1 << n) - 1;
int num = 0;
for (int i = 0; i < n; ++i) {
bool find_it = false;
for (int j = 0; j < n; ++j) {
char c = 'a' + j;
if ((mask & (1 << j)) != 0 && (!equal || c >= minStr[i])) {
int num0 = num;
int remain_max_inv = GetMaxInv(mask ^ (1 << j), n);
for (int k = 0; k < i; ++k) {
if (s[k] > c) {
++num0;
}
}
if (num0 + remain_max_inv >= minInv) {
s += c;
num = num0;
if (c > minStr[i]) {
equal = false;
}
find_it = true;
mask ^= 1 << j;
break;
}
}
}
if (!find_it) {
return "";
}
}
return s;
} int GetMaxInv(int remain_mask, int n) {
int result = 0;
int pre = 0;
for (int i = n - 1; i >= 0; --i) {
if ((remain_mask & (1 << i)) != 0) {
result += pre;
} else {
++pre;
}
}
result += (n - pre) * (n - pre - 1) / 2;
return result;
}
};
code for problem2
#include <stdint.h>
#include <algorithm>
#include <iostream>
#include <string>
#include <vector> class Spacetsk {
static const int64_t mod = 1000000007; public:
int countsets(int L, int H, int K) {
Init(std::max(L, H) + 1);
int64_t r = Binomial(H + 1, K) * (L + 1) % mod;
if (K == 1) {
return static_cast<int>(r);
}
for (int x = 1; x <= L; ++x) {
for (int y = H; y >= 1; --y) {
if (Gcd(x, y) != 1) {
continue;
}
r += (Compute1(L, H, K, x, y) + Compute2(L, H, K, x, y)) << 1;
r %= mod;
}
}
return static_cast<int>(r);
} private:
int64_t Compute1(int L, int H, int K, int x, int y) {
int x_right;
if (H % y == 0) {
x_right = L - H / y * x;
} else {
x_right = L - H * x / y - 1;
}
if (x_right < 0) {
return 0;
}
int c = x_right + 1;
int num = H / y + 1;
return Binomial(num, K) * static_cast<int64_t>(c) % mod;
} int64_t Compute2(int L, int H, int K, int x, int y) {
int x_right;
if (H % y == 0) {
x_right = L - H / y * x;
} else {
x_right = L - H * x / y - 1;
}
++x_right;
if (x_right < 0) {
x_right = 0;
}
int64_t r = 0;
int64_t length = L - x_right;
if ((length + 1) % x != 0) {
int num = length / x + 1;
int c = length % x + 1;
r += Binomial(num, K) * static_cast<int64_t>(c) % mod;
length -= c;
}
int max_num = length / x + 1;
r += Binomial(max_num + 1, K + 1) * static_cast<int64_t>(x);
r %= mod;
return r;
} int64_t Gcd(int64_t x, int64_t y) { return y == 0 ? x : Gcd(y, x % y); } int64_t Binomial(int a, int b) {
if (a < b) {
return 0;
}
if (a == 0 || a == b) {
return 1;
}
return p[a] * q[b] % mod * q[a - b] % mod;
} void Init(int n) {
p.resize(n + 2);
q.resize(n + 2);
p[0] = q[0] = 1;
for (int64_t i = 1; i < p.size(); ++i) {
p[i] = p[i - 1] * static_cast<int64_t>(i) % mod;
q[i] = Pow(p[i], mod - 2);
}
} int64_t Pow(int64_t a, int64_t b) {
int64_t r = 1;
while (b > 0) {
if ((b & 1) == 1) {
r = r * a % mod;
}
a = a * a % mod;
b >>= 1;
}
return r;
} std::vector<int64_t> p;
std::vector<int64_t> q;
};
code for problem3
#include <vector>
#include <iostream>
using namespace std; class SetAndSet {
public:
long long countandset(vector<int> A) {
long long all = 0;
for (size_t i = 0; i < A.size(); ++i) {
all &= A[i];
}
for (size_t i = 0; i < A.size(); ++i) {
A[i] ^= all;
}
std::vector<std::vector<int>> v(20, std::vector<int>());
for (int i = 0; i < 20; ++i) {
for (size_t j = 0; j < A.size(); ++j) {
if ((A[j] & (1 << i)) == 0) {
v[i].push_back(static_cast<int>(j));
}
}
}
std::vector<int> f(A.size());
for (size_t i = 0; i < f.size(); ++i) {
f[i] = i;
}
return dfs(0, f, 1ll, v, A);
} long long dfs(size_t dep, const std::vector<int> &f, long long sgn,
const std::vector<std::vector<int>> &v,
const std::vector<int> &A) {
if (dep == v.size()) {
int tot = 0;
for (size_t i = 0; i < f.size(); ++i) {
if (f[i] == static_cast<int>(i)) {
++tot;
}
}
return (1ll << tot) * sgn;
}
long long result = dfs(dep + 1, f, sgn, v, A);
if (!v[dep].empty()) {
static std::vector<int> h(50, 0);
static int index = 0;
std::vector<int> f_bak = f;
++index;
for (size_t i = 0; i < v[dep].size(); ++i) {
h[f[v[dep][i]]] = index;
}
int root = f_bak[v[dep][0]];
for (size_t i = 0; i < A.size(); ++i) {
if (h[f_bak[i]] == index) {
f_bak[i] = root;
}
}
result += dfs(dep + 1, f_bak, -sgn, v, A);
}
return result;
}
};
topcoder srm 545 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)其 ...
随机推荐
- RNN实例
https://blog.csdn.net/jmh1996/article/details/78821216
- selenium-grid 分布式 实现同一脚本在不同pc上运行
1.使用版本:selenium 3.11.0chrome 65phantomjs 2.1.1selenium-server selenium-server-standalone-2.46.0.jar ...
- byte & 0xff char 转换
https://blog.csdn.net/lixingtao0520/article/details/75450883 版权声明:本文为博主原创文章,转载请注明作者与出处,http://blog.c ...
- html5的理解
1.良好的移动性,以移动设备为主 2.响应式设计,以适应自动变化的屏幕尺寸 3.支持离线缓存技术,webStorage本地缓存 4.新增canvas.video.audio等新标签元素,新增特殊内容元 ...
- 通过 Java 线程堆栈进行性能瓶颈分析
改善性能意味着用更少的资源做更多的事情.为了利用并发来提高系统性能,我们需要更有效的利用现有的处理器资源,这意味着我们期望使 CPU 尽可能出于忙碌状态(当然,并不是让 CPU 周期出于应付无用计算, ...
- 第三节 深入JavaScript
函数的返回值:(把函数体内的数据传出到函数体外) 什么是函数的返回值:函数执行结果.可以没有返回值 一种函数应该只返回一种类型的值 函数传参:(与函数返回值相反,把外面数据传入函数体内) 可变参(不定 ...
- Zynq ZC706 传统方式移植Linux -- 编译u-boot
我用的是zc706不是zed 基本思路是: 1.安装交叉编译工具(见 https://www.cnblogs.com/idyllcheung/p/10532654.html ) 2.下载xilinx ...
- intelliJ IDEA之使用svn或git管理代码
intelliJ IDEA之使用svn管理代码 1.VCS—>import into Version Control—>Share Project(Subversion) 2.点击+ ...
- mybatis总结之一
今日内容:mybatis数据持久层的一种表现,在一定程度上,取代了jdbc. 1.建maven...... 在pom.xml中进行配置,添加mabatis包,junit测试jar包,添加连接mysql ...
- django的url配置
在一个请求到达的时候,最先达到的就是视图层,然后根据url映射到视图函数.这一部分我们来说明url的配置. 概述 为了给一个应用设计URL,你需要创建一个Python 模块,通常称为URLconf(U ...