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)其 ...
随机推荐
-
MPLS与LDP从入门到了解
多协议标签交换(MPLS)是一种用于快速转发数据包的技术,它的出现就是为了提高转发效率.因为IP转发大多靠软件进行,在转发的每一跳都要进行至少一次最长匹配查找,操作复杂导致转发速度比较慢.有些厂商借鉴 ...
-
关系数据库—SQL学习笔记
SQL的特点: 综合统一 高度非过程化(存取路径的选择以及SQL的操作过程由系统自动完成) 面向集合的操作方式,以同一种语法结构提供多种使用方法(可以在终端键盘上直接键入SQL命令对数据库进行操作,也 ...
-
移动混合应用HTML5数据查询优化
项目介绍 pheongap混合应用,跨平台,做应用加工厂提供应用模板编辑器~ 本地应用,完全是模拟IOS,安卓原生应用的实现,所以支持14种手势,所有PPT动画,视觉差效果,等等功能组合... 这是I ...
-
php正则贪婪匹配与非贪婪匹配一些例子
http://www.111cn.net/phper/210/55600.htm 贪婪模式匹配的原则是: 在可匹配也可不匹配的情况下, 优先匹配,直到不能匹配成功的情况下,记录备选状态,并把匹配控制交 ...
-
C#的同步和异步调用方法
同步和异步大家都明白什么意思,在这里不多介绍了. namespace ConsoleTest { class Program { static void Main(string[] args) { C ...
-
【转】Java 集合系列03之 ArrayList详细介绍(源码解析)和使用示例
原文网址:http://www.cnblogs.com/skywang12345/p/3308556.html 上一章,我们学习了Collection的架构.这一章开始,我们对Collection的具 ...
-
MVC EF 修改 封装类 通用泛型方法(二)
修改 这个 方法 如下. 排除 null 值. /// <summary> /// 修改 多数 数据, 个别数据除外, proNames 不写 则是 修改全部 /// </summa ...
-
java第十二次作业
1. 本周学习总结 1.1 以你喜欢的方式(思维导图或其他)归纳总结多流与文件相关内容. 2. 书面作业 将Student对象(属性:int id, String name,int age,doubl ...
-
python concurrent.futures
python因为其全局解释器锁GIL而无法通过线程实现真正的平行计算.这个论断我们不展开,但是有个概念我们要说明,IO密集型 vs. 计算密集型. IO密集型:读取文件,读取网络套接字频繁. 计算密集 ...
-
最短路(SPFA)
SPFA是Bellman-Ford算法的一种队列实现,减少了不必要的冗余计算. 主要思想是: 初始时将起点加入队列.每次从队列中取出一个元素,并对所有与它相邻的点进行修改,若某个相邻的点修改成功,则将 ...