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)其 ...
随机推荐
- LeetCode108.将有序数组转换为二叉搜索树
将一个按照升序排列的有序数组,转换为一棵高度平衡二叉搜索树. 本题中,一个高度平衡二叉树是指一个二叉树每个节点 的左右两个子树的高度差的绝对值不超过 1. 示例: 给定有序数组: [-10,-3,0, ...
- Mongodb 分组查询例子
db.tblCard.aggregate([ { $match: { "sNo": { " ...
- hessian 在spring中的使用 (bean 如 Dao无法注入的问题)
hessian的主要结构分客户端与服务端,中间基于http传输.客户端主要做的事情是把对远程接口调用序列化为流,并传输到服务端:服务端主要做的事情是把传输过来的流反序列化为对服务的请求,调用相应服务后 ...
- oracle 修改表结构,增加列,删除列等
增加一列:ALTER TABLE yourTabbleName ADD columnName dataType; 增加多列:ALTER TABLE yourTabbleName ADD (column ...
- 记前些日子archlinux更新后无法调节声音的解决方法
桌面环境用的是xfce4. 自从某次更新过后,panel中调节声音的插件变成了 xfce4-pulseaudio-plugin.然后就发现在panel中无法调节声音了. 在这个插件的属性中发现了一项设 ...
- Java类访问控制
public protected default private 本类 可见 可见 可见 可见 本类所在包 可见 可见 可见 不可见 其他包中的子类 可见 可见 不可见 不可见 其他包中的非子类 ...
- 《大话设计模式》c++实现 抽象工厂模式
为了更清晰地理解工厂方法模式,需要先引入两个概念: 产品等级结构 :产品等级结构即产品的继承结构,如一个抽象类是电视机,其子类有海尔电视机.海信电视机.TCL电视机,则抽象电视机与具体品牌的电视机之间 ...
- codeforces 975C Valhalla Siege
题意: 有n个巫师站成一列,每个巫师有自己的血量. 一个人射箭攻击他们,每次造成若干点伤害,巫师按照给定的顺序承受伤害,如果伤害大了,那么死掉,伤害落到下一个巫师身上. 如果一轮攻击之后,所有的巫师都 ...
- Java WEB 笔记
1. 部署并启动 tomcat 服务器 1). 解压 apache-tomcat-version 到一个非中文目录下 2). 配置一个环境变量,JAVA_HOME(指向 JDK 安装目录)或 JRE_ ...
- python csv文件转换成xml, 构建新xml文件
csv文件 code from xml.etree.ElementTree import Element,ElementTree,tostring import json,csv def csvtox ...