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的更多相关文章

  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. node.js连接本地数据库及json返回数据

    新建一个文件夹node.js,目录下打开命令初始化一下 cnpm init 然后下载express框架 cnpm install express --save 接着下载数据库的依赖 cnpm inst ...

  2. div上下左右居中方法

    方法一:在浏览器中只有一个div的情况 { position:fixed; position:fixed; ; ; ; ; margin:auto; } 方法一 方法二:一个父元素div和一个已知宽度 ...

  3. oauth2.0+app方式 webgis 授权

    .认证方式有三种 Oauth2.0, Token-based http/windows 二.用户登录与应用登录区别 两者区别在于:当用户登录时,服务器端平台是否直接识别登录信息和验证登录信息. 应用登 ...

  4. orm查询语法参考文章

    1.参考博客 http://blog.csdn.net/OyangYujun/article/details/45938905 ORMLite完全解析(三)官方文档第三章.自定义查询构造器 Custo ...

  5. gedit emacs

    emacs常用操作: 1)C-g:退出当前命令 2)C-x C-f:搜索文件打开 3)C-s:向前搜索 C-r:向后搜索 4)C-x 2:水平分割窗口 C-x 3:竖直分割窗口 5)C-x o:切换窗 ...

  6. Openstack CentOS6.5 ALL IN ONE 安装

    本文档以RDO的方式安装单节点.单网卡的Openstack. RDO是可在Red Hat Enterprise Linux.Fedora及其变体上运行的社区支持OpenStack版本.部署简单方便,R ...

  7. HighCharts学习笔记(一)

    HighChars基本概述 Highcharts是一个纯js写成的插件库,很好的外观表现可以满足任何图标需求. 开始使用chart之前进行配置 全局配置: Highcharts.setOptions( ...

  8. 对象的copy

    一般来讲,java中,对象的copy一般是通过Beans.copy(B, A);用来将A对象复制给B对象,包括对象里面的属性和值. 但但但...... 这样做,有一个很严重的问题,那就是:如果把A对象 ...

  9. golang学习笔记7 使用beego swagger 实现API自动化文档

    golang学习笔记7 使用beego swagger 实现API自动化文档 API 自动化文档 - beego: 简约 & 强大并存的 Go 应用框架https://beego.me/doc ...

  10. golang学习笔记5 用bee工具创建项目 bee工具简介

    golang学习笔记5 用bee工具创建项目 bee工具简介 Bee 工具的使用 - beego: 简约 & 强大并存的 Go 应用框架https://beego.me/docs/instal ...