problem1 link

设第一个数字为$x$,那么第2到第$n$个数字都可以表示成$a+bx$的形式,其中$b=1$或者$b=-1$.然后可以求出关于$x$的一些范围,求交集即可.

problem2 link

设$f[i][r][g][b]$表示前$i$个已经染色完毕,第$i$颜色为$(r,g,b)$的概率.假设由$(r,g,b)$可以转移到的状态个数为$T$,那么每个可以转移到的状态$(r^{'},g^{'},b^{'})$都可以得到$\frac{f[i][r][g][b]}{T}$的贡献.暴力转移的复杂度太高.如果没有$d_{1}$的限制,那么$r,g,b$可以转移到的状态,如果将其看作三维空间中的坐标,是以$(r,g,b)$为中心的边长为$2d_{2}+1$的立方体.这样的更新可以整块进行.有了$d_{1}$,可以将至少有一个大于等于$d_{1}$改为所有的情况减去都小于$d_{1}$的情况.这样的话,$r,g,b$可以转移到的状态为以$r,g,b$为中心的边长为$2d_{2}+1$的立方体去掉以$r,g,b$为中心的边长为$2d_{1}+1$的立方体.

problem3 link

首先,由于10=2*5.这样将问题分解为计算模2以及模5的种类数.然后乘起来即可.考虑计算这个子问题.令$p=2$或者$5$.

由于如果$output[i]=0$,那么对应的区间一定有至少一个0,反之,一定是一个0也不会有.那么可以将$N$个数字分成两部分,一定不会出现0的部分以及可能有0的部分.

(1)对于可能有0的部分的计算:设$f[i][j]$表示放置了前$i$个数字,最后一个放置0的位置在$j$的方案数.

(2)对于一定没有0的部分的计算:首先,如果两个不同的区间$[L_{1},R_{1}],[L_{2},R_{2}]$的关系是$L_{1}=L_{2}$或者$R_{1}=R_{2}$,那么可以将其中一个较大的区间强行分成两段.这样最后所有的区间的两两之间的关系一定以下三种:不相交,一个是另一个的真子集,相交但是不是真子集.如下图所示,有绿,红,蓝,黄,黑5个区间.对于每个区间来说,如果区间内前面的元素确定了,那么区间的最后一个元素就是唯一的(因为$p$是素数).这样的话,只有问号的位置是可以随意放置的.

code for problem1

#include <vector>
#include <string>
#include <limits>
using namespace std; class ImportantSequence {
public:
int getCount(vector<int> B, string operators) {
int64_t left = 1;
int64_t right = std::numeric_limits<int64_t>::max();
int64_t a = 0;
int b = 1;
for (size_t i = 0; i < B.size(); ++i) {
int64_t val = static_cast<int64_t>(B[i]);
if (operators[i] == '+') {
a = val -a;
b = -b;
} else {
a = a - val;
}
if (b == 1) {
left = std::max(left, 1 - a);
} else {
right = std::min(right, a - 1);
}
if (left > right) {
return 0;
}
}
if (right == std::numeric_limits<int64_t>::max()) {
return -1;
}
return static_cast<int>(right - left + 1);
}
};

  

code for problem2

#include <algorithm>
#include <cstring>
#include <iostream> const int MAXN = 40;
const int MAX = 50;
double f[MAXN][MAX + 1][MAX + 1][MAX + 1]; class RandomColoring {
public:
double getProbability(int N, int maxR, int maxG, int maxB, int startR,
int startG, int startB, int d1, int d2) {
this->max_r = maxR;
this->max_g = maxG;
this->max_b = maxB;
f[0][startR][startG][startB] = 1;
for (int i = 1; i < N; ++i) {
for (int r = 0; r < maxR; ++r) {
const std::pair<int, int> rd2 = ComputeRage(r, d2, maxR);
const std::pair<int, int> rd1 = ComputeRage(r, d1 - 1, maxR);
for (int g = 0; g < maxG; ++g) {
const std::pair<int, int> gd2 = ComputeRage(g, d2, maxG);
const std::pair<int, int> gd1 = ComputeRage(g, d1 - 1, maxG);
for (int b = 0; b < maxB; ++b) {
const std::pair<int, int> bd2 = ComputeRage(b, d2, maxB);
const std::pair<int, int> bd1 = ComputeRage(b, d1 - 1, maxB);
const int s1 = Size(rd2) * Size(gd2) * Size(bd2);
const int s0 = d1 > 0 ? Size(rd1) * Size(gd1) * Size(bd1) : 0;
if (s1 == s0) {
continue;
}
const double e = f[i - 1][r][g][b] / (s1 - s0);
Add(i, rd2.first, gd2.first, bd2.first, rd2.second, gd2.second,
bd2.second, e);
if (d1 > 0) {
Add(i, rd1.first, gd1.first, bd1.first, rd1.second, gd1.second,
bd1.second, -e);
}
}
}
}
for (int r = 0; r < maxR; ++r) {
for (int g = 0; g < maxG; ++g) {
for (int b = 0; b < maxB; ++b) {
f[i][r][g][b] += Get(i, r - 1, g, b) + Get(i, r, g - 1, b) +
Get(i, r, g, b - 1) - Get(i, r - 1, g - 1, b) -
Get(i, r - 1, g, b - 1) - Get(i, r, g - 1, b - 1) +
Get(i, r - 1, g - 1, b - 1);
}
}
}
}
double result = 0;
for (int x = 0; x < maxR; ++x) {
for (int y = 0; y < maxG; ++y) {
for (int z = 0; z < maxB; ++z) {
if (!(abs(x - startR) <= d2 && abs(y - startG) <= d2 &&
abs(z - startB) <= d2 &&
(abs(x - startR) >= d1 || abs(y - startG) >= d1 ||
abs(z - startB) >= d1))) {
result += f[N - 1][x][y][z];
}
}
}
}
return result;
} double Get(int t, int x, int y, int z) {
if (x >= 0 && y >= 0 && z >= 0) {
return f[t][x][y][z];
}
return 0.0;
} void Add(int t, int x, int y, int z, int x1, int y1, int z1, double val) {
Add(t, x, y, z, val);
Add(t, x, y, z1 + 1, -val);
Add(t, x, y1 + 1, z, -val);
Add(t, x1 + 1, y, z, -val);
Add(t, x1 + 1, y1 + 1, z, val);
Add(t, x1 + 1, y, z1 + 1, val);
Add(t, x, y1 + 1, z1 + 1, val);
Add(t, x1 + 1, y1 + 1, z1 + 1, -val);
}
void Add(int t, int x, int y, int z, double val) {
if (x < max_r && y < max_g && z < max_b) {
f[t][x][y][z] += val;
}
} std::pair<int, int> ComputeRage(int x, int d, int max_x) {
return {std::max(0, x - d), std::min(x + d, max_x - 1)};
}
int Size(const std::pair<int, int> &range) {
return range.second - range.first + 1;
} private:
int max_r, max_g, max_b;
};

  

code for problem3

#include <string>
#include <vector>
#include <limits>
#include <iostream>
using namespace std; class ProductQuery {
static const int64_t mod = 1000000007; public:
int theInput(int N, vector<int> Qfrom, vector<int> Qto, vector<int> output) {
auto ModFunc = [output](const int p) -> std::vector<int> {
std::vector<int> r;
for (auto x : output) {
r.push_back(x % p);
}
return r;
};
return static_cast<int>(Compute(N, Qfrom, Qto, ModFunc(2), 2) *
Compute(N, Qfrom, Qto, ModFunc(5), 5) %
mod);
} private:
int64_t Compute(int N, const std::vector<int> &qfrom,
const std::vector<int> &qto, const std::vector<int> &output,
const int p) {
std::vector<int> not_zero(N, 0);
for (size_t i = 0; i < output.size(); ++i) {
if (0 != output[i]) {
for (int j = qfrom[i]; j <= qto[i]; ++j) {
not_zero[j] = 1;
}
}
}
int zero_index = 0;
int not_zero_index = 0;
std::vector<int> zero_map(N, -1);
std::vector<int> not_zero_map(N, -1);
for (int i = 0; i < N; ++i) {
if (not_zero[i] == 0) {
zero_map[i] = zero_index++;
} else {
not_zero_map[i] = not_zero_index++;
}
}
std::vector<int> zero_qfrom;
std::vector<int> zero_qto;
std::vector<int> not_zero_qfrom;
std::vector<int> not_zero_qto;
std::vector<int> not_zero_output;
auto FindValidRange = [](const std::vector<int> &elements, int left,
int right) -> std::pair<int, int> {
int left_index = -1;
int right_index = -1;
for (int j = left; j <= right; ++j) {
if (elements[j] != -1) {
if (left_index == -1) {
left_index = elements[j];
}
right_index = elements[j];
}
}
return {left_index, right_index};
};
for (size_t i = 0; i < output.size(); ++i) {
if (output[i] == 0) {
auto r = FindValidRange(zero_map, qfrom[i], qto[i]);
if (r.first == -1) {
return 0;
}
zero_qfrom.push_back(r.first);
zero_qto.push_back(r.second);
} else {
auto r = FindValidRange(not_zero_map, qfrom[i], qto[i]);
if (r.first == -1) {
return 0;
}
not_zero_qfrom.push_back(r.first);
not_zero_qto.push_back(r.second);
not_zero_output.push_back(output[i]);
}
}
return Place0(zero_index, zero_qfrom, zero_qto, p) *
NotPlace0(not_zero_index, not_zero_qfrom, not_zero_qto,
not_zero_output, p) %
mod;
}
int64_t Place0(int N, const std::vector<int> &qfrom,
const std::vector<int> &qto, const int p) { if (N == 0) {
return 1;
}
auto CheckForceZero = [qfrom, qto](int pre_zero_index,
int cur_index) -> bool {
for (size_t i = 0; i < qfrom.size(); ++i) {
if (qfrom[i] > pre_zero_index && qto[i] == cur_index) {
return true;
}
}
return false;
};
auto EncodeIndex = [](int t) { return t + 1; };
std::vector<std::vector<int64_t>> f(N, std::vector<int64_t>(N + 1, 0));
f[0][EncodeIndex(0)] = 1;
if (!CheckForceZero(-1, 0)) {
f[0][EncodeIndex(-1)] = p - 1;
}
for (int i = 1; i < N; ++i) {
for (int j = -1; j < i; ++j) {
const int64_t val = f[i - 1][EncodeIndex(j)];
Add(f[i][EncodeIndex(i)], val);
if (!CheckForceZero(j, i)) {
Add(f[i][EncodeIndex(j)], val * (p - 1) % mod);
}
}
}
int64_t result = 0;
for (int i = -1; i < N; ++i) {
Add(result, f[N - 1][EncodeIndex(i)]);
}
return result;
}
int64_t NotPlace0(int N, const std::vector<int> &qfrom,
const std::vector<int> &qto, const std::vector<int> &output,
const int p) {
if (N == 0) {
return 1;
}
std::vector<int64_t> rev_table(p);
for (int i = 1; i < p; ++i) {
for (int j = 1; j < p; ++j) {
if (i * j % p == 1) {
rev_table[i] = j;
break;
}
}
}
std::vector<bool> delete_items(output.size(), false);
std::vector<int> last_qfrom = qfrom;
std::vector<int> last_qto = qto;
std::vector<int> last_output = output;
bool updated = true;
int total_range = static_cast<int>(output.size());
while (updated) {
updated = false;
for (size_t i = 0; i < output.size(); ++i) {
if (!delete_items[i]) {
for (int j = i + 1; j < output.size(); ++j) {
if (!delete_items[j]) {
if (last_qfrom[i] == last_qfrom[j] && last_qto[i] == last_qto[j]) {
if (last_output[i] != last_output[j]) {
return 0;
}
--total_range;
delete_items[j] = true;
updated = true;
} else if (last_qfrom[i] == last_qfrom[j]) {
if (last_qto[i] < last_qto[j]) {
last_qfrom[j] = last_qto[i] + 1;
last_output[j] =
last_output[j] * rev_table[last_output[i]] % p;
} else {
last_qfrom[i] = last_qto[j] + 1;
last_output[i] =
last_output[i] * rev_table[last_output[j]] % p;
}
updated = true;
} else if (last_qto[i] == last_qto[j]) {
if (last_qfrom[i] < last_qfrom[j]) {
last_qto[i] = last_qfrom[j] - 1;
last_output[i] =
last_output[i] * rev_table[last_output[j]] % p;
} else {
last_qto[j] = last_qfrom[i] - 1;
last_output[j] =
last_output[j] * rev_table[last_output[i]] % p;
}
updated = true;
}
}
}
}
}
}
int64_t result = 1;
for (int i = 1; i <= N - total_range; ++i) {
result = result * (p - 1) % mod;
}
return result;
}
void Add(int64_t &x, int64_t y) {
x += y;
if (x >= mod) {
x -= mod;
}
}
};

  

topcoder srm 540 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. c# webapi 跳转

    c# webapi 跳转  public HttpResponseMessage Post() {     // ... do the job     // now redirect     Http ...

  2. windows环境下搭建RocketMQ

    https://blog.csdn.net/hsl_1990_08_15/article/details/80077552 安装完rocketmq后,报磁盘空间不足,只需要修改启动脚本runbroke ...

  3. uvalive 3276 The Great Wall Game

    题意: 一个n * n的棋盘上放着n个棋子,现在要求把这n个棋子用最少的步数移到同一条直线上,即同一列同一行或者同一对角线(两条).输出最少的步数(只能往四个方向移动,即正东,正西,正南,正北). 思 ...

  4. SQL 中的连接查询

    关于SQL的应用,肯定离不开查询,而相对复杂的查询,总是离不开对表的连接,单个表操作的并不罕见,但是在应用环境大多数的查询都是针对2.3个表甚至更多的表7,至于连接,有内连接.外链接.交叉连接之分,每 ...

  5. QtCreator 调试源码

    [1]安装源码 声明:要想调试进入Qt源码,必须首先保证我们安装了Qt源码.下面说明安装Qt源码注意事项. 一般安装过程(默认不安装源码): 安装源码过程(需要自己设置,点击“全选”): 综上所述:Q ...

  6. Java Redis JNI

    基本参考菜鸟教程,java下载直接安装,注意文件名和类名需要一致的问题: redis下载以后按菜鸟教程linux下安装,方式编译运行ok: Java使用redis按菜鸟教程下载.jar,保存在本地某个 ...

  7. python中装饰器修复技术

    python装饰器@wraps作用-修复被装饰后的函数名等属性的改变 Python装饰器(decorator)在实现的时候,被装饰后的函数其实已经是另外一个函数了(函数名等函数属性会发生改变), 为了 ...

  8. 用django统计代码行数+注释行数

    实现统计代码行数: 1.首先在url.py中配置 from django.conf.urls import url from django.contrib import admin from app0 ...

  9. 移动端点击返回时强制页面刷新解决办法(pageshow)

    在做移动端项目的时候经常遇到这样一个功能比如: 返回后页面不刷新,一些失效的信息依然显示在页面上.这个问题在iphone手机上会出现,在Android手机上返回时会自动刷新(由于手机机器种类不多,无法 ...

  10. flask 在模板中渲染表单

    在模板中渲染表单 为了能够在模板中渲染表单,我们需要把表单类实例传入模板.首先在视图函数里实例化表单类LoginForm,然后再render_template()函数中使用关键脑子参数form将表单实 ...