DAY 5

廖俊豪神仙出题


T1

最小差异矩阵(a.cpp, a.in, a.out)

【题目描述】

有一个 n*m 的矩阵,矩阵的每个位置上可以放置一个数。对于第 i 行,第 i 行的差异定义为该行的最大数和最小数的差。一个矩阵的差异,定义为矩阵中每一行差异的最大值。现在给定 k 个数 v[1..k],问:从这 k 个数中选 n*m 个数放入矩阵,能够得到的矩阵的差异最小值是多少。

【输入格式】

第一行三个整数,k, n, m,表示有 k 个数可选,矩阵的行数和列数分别为 n 和 m。

第二行 k 个整数,表示备选的数 v[1..k]。

【输出格式】

输出一个数,表示能够得到的最小差异值

【样例输入】

5 2 2

7 5 8 2 3

【样例输出】

1

【数据范围与提示】

对于 30%的数据,k <= 10, n <= 3, m <= 3

对于 100%的数据,n * m <= k <= 100000, n, m <= 1000,0 <= v[i] <= 10^9

256MB,1s

题解

先排序

二分差异的最大值k,然后贪心

放数一定是连续的,将某一段放到一行

从前往后找,如果说从某个数开始往后数m个数,最大值减去最小值小于等于枚举的k就合法,那么就把这m个数放到同一行,最后判断是否能够凑出n行

O(klogC)

#include<bits/stdc++.h>
using namespace std; const int maxn = 1e5 + ;
int n, m, k, v[maxn]; int judge(int d)
{
int tmp = ;
for (int i=; i+m-<=k; ++i)
{
if (v[i+m-] - v[i] <=d)
++tmp, i += m - ;
}
if (tmp >= n) return ;
return ;
} int main()
{
freopen("a.in", "r", stdin);
freopen("a.out", "w", stdout);
scanf("%d%d%d", &k, &n, &m);
for (int i=; i<=k; ++i)
scanf("%d", &v[i]);
sort(v + , v + k + );
int left = , right = 1e9;
while (left < right)
{
int mid = (left + right) / ;
if (judge(mid))
right = mid;
else
left = mid + ;
}
printf("%d\n", left);
return ;
}

T2

分割序列(b.cpp, b.in, b.out)

【题目描述】

给定一个长度为 n 的序列 v[1..n],现在要将这个序列分成 k 段(每段都不能为空),定义每一段的权值为该段上的所有数的或和。定义整个序列的权值为每段权值的和。问:这个序列的最大权值为多少。

【输入格式】

第一行两个数 n 和 k,意义如题意所示。

第二行 n 个数,表示这个序列 v[1..n]。

【输出格式】

输出一个数,代表这个序列的最大权值。

【输入样例】

5 2

7 5 8 2 3

【输出样例】

22

【数据范围与时空限制】

对于 30%的数据,n <= 10, k <= 10

对于 60%的数据,n <= 100, k <= 100

对于 100%的数据,k <= n <= 2000,1 <= v[i] <= 5 * 10^5

256MB,1s

题解

f[i][j]表示前i个数分j段的最大权值和  ans=f[n][k]

可以先预处理出每一段的或和sum[i][j]

转移:f[i][j]=max(f[l][j-1]+sum[l+1][i])(l<i) l表示将第i+1到第i个数当成一段

60pts

怎么优化?

还是先n^2预处理

找单调性  f[l][j-1]随着l的增加递增  sum[l+1][i]随着l的增加而递减

Sum是按位或:比如变化到1e6,最多变化20次

如果按sum值分段,那么最优的一定是某一段sum的最后加上f的值

那么对于每一个j,我们可以枚举它前面的点i,把sum分段

If(sum[i][j]!=sum[i+1][j])  vector[j].push_back(i);

在刚才枚举l的时候就可以变成枚举决策点了,这一维变成了log的复杂度

O(n*k*logC)

#include <bits/stdc++.h>
using namespace std; const long long inf = 1ull << << ;
const int maxn = ;
vector<int> point[maxn];
int n, K, v[maxn], sum[maxn][maxn];
long long f[maxn][maxn];
int main()
{
freopen("b.in", "r", stdin);
freopen("b.out", "w", stdout);
cin >> n >> K;
for (int i=; i<=n; ++i) cin >> v[i];
for (int i=; i<=n; ++i) sum[i][i] = v[i];
for (int i=; i<n; ++i)
for (int j=i+; j<=n; ++j)
sum[i][j] = sum[i][j-] | v[j];
for (int i=; i<=n; ++i)
{
point[i].push_back(i);
for (int j=i-; j>=; --j)
if (sum[j][i] != sum[j+][i])
point[i].push_back(j);
}
for (int k=; k<=K; ++k)
for (int i=; i<=n; ++i)
{
if (i < k) continue;
for (int j=; j<point[i].size(); ++j)
{
int x = point[i][j];
if (x >= k)
f[i][k] = max(f[i][k], f[x-][k-] + sum[x][i]);
}
}
cout << f[n][K] << endl;
return ;
}

T3

树的魔法值(C.cpp, C.in, C.out)

【题目描述】

有一棵 k+1 层的满二叉树,那么该树有 2^k 个叶子节点。给定 n 个机器人(n=2^k),编号从 1—n,编号为 i 的机器人的权值为 v[i]。我们现在要将这 n 个机器人分别放置在这 n 个叶子节点上,每个叶子节点放且只能放一个机器人。叶子节点的权值为该叶子节点上的机器人的权值。非叶子节点的权值定义为该树中编号最大的机器人的权值。每个非叶子节点除了权值以外,还有一个魔法值,该点的魔法值为其左右儿子节点的权值的乘积。整棵树的魔法值定义为非叶子节点的魔法值的和。

问:将这 n 个机器人随机地放在这 n 个叶子节点上,树的魔法值的期望为多少。

【输入格式】

第一行为一个整数 k,含义如题所示。

第二行为 2^k 个整数,依次表示这 n 个机器人的权值。

【输出格式】

假设答案为一个不可约分数 P/Q,则输出在模 1e9+7 意义下的 P * (Q^-1)模 1e9+7 的值。

【样例输入 1】

2

1 3 5 7

【样例输出 1】

59

【样例解释】

对于 n=4 的情况,机器人共有 24 种不同的安放方案。其中,本质不同的有 3 种,分别是((1,3),(5,7)), ((1,5),(3,7)), ((1,7),(5,3)),魔法值分别为 1*3+5*7+3*7=59, 1*5+3*7+5*7=61,1*7+5*3+5*7=57, 答案为(57+59+61)/3 = 59。

【样例输入 2】

2

1 5 3 7

【样例输出 2】

333333390

【数据范围与时空限制】

30%的数据,k <= 3

60%的数据,k <= 10

100%的数据,k <= 18

256MB,1s

题解:

30pts  k<=3 --> n<=8  n!暴力  期望:所有情况的值加起来取平均  就是除以n!

60pts  k<=10,n<=1024  求出所有情况的魔法值的和?

考虑两个点x和y在第d层对答案的贡献

分步考虑  考虑两个点在第d层相遇,那么应该算清楚第d层相遇了多少次,统计出来就可以算出贡献

Σ(v[x]*v[y]*times[x][y])

怎么算?

设x>y

在y的子树里面,一定有2^d-1个小于y的

1)在y-1个数里面,选择2^d -1个小于y的方案数C(y -1, 2^y -1)

2)在x- 2^d -1个数里面,选择2^d -1个小于x的方案数 C(x- 2^d -1 , 2^d-1)

3) 其他n- 2^(d+1) 任意排列n- 2^(d+1)!

4) 考虑x和y相遇的位置  2^(k-d)

5) 上面的都不对,因为要求排列,所以是A

6) x和y的位置可以互换  *2

x>2^(d+1)  y>=2^d  x>y

bits[i]表示2^i

c[i][j]表示C(i,j)

fac[i]表示i!

枚举x,y,d

O(n^2logn)

100pts

优化式子本身

发现最后一部分只在枚举x的时候和y有关,所以可以把它放到外面去

预处理出后缀和,枚举d和y就行了

#include <bits/stdc++.h>
using namespace std; const int mod = 1e9 + ;
const int maxn = ( << ) + ;
typedef long long LL; LL fac[maxn], inv_fac[maxn], bit[maxn], sum[maxn];
int n, v[maxn], k;
int powmod(int x, int times)
{
LL tmp = ;
while (times > )
{
if (times & ) tmp = tmp * x % mod;
x = (LL)x * x % mod;
times >>= ;
}
return tmp;
} LL C(int x, int y)
{
if (x < y) return ;
return fac[x] * inv_fac[y] % mod * inv_fac[x-y] % mod;
} int main()
{
freopen("c.in", "r", stdin);
freopen("c.out", "w", stdout);
fac[] = ; for (int i=; i<maxn; ++i) fac[i] = fac[i-] * i % mod;
inv_fac[maxn-] = powmod(fac[maxn-], mod - );
for (int i=maxn-; i>=; --i) inv_fac[i] = inv_fac[i+] * (i + ) % mod;
bit[] = ; for (int i=; i<=; ++i) bit[i] = bit[i-] * ; scanf("%d", &k);
n = bit[k];
for (int i=; i<=bit[k]; ++i) scanf("%d", &v[i]);
//for (int i=bit[k]; i>=1; --i) scanf("%d", &v[i]);
LL ans = ;
for (int d=; d<=k; ++d)
{
LL tmp = ;
for (int i=n; i>=bit[d]; --i)
sum[i] = (sum[i+] + C(i--bit[d-], bit[d-]-) * v[i]) % mod;
for (int j=n-; j>=bit[d-]; --j)
tmp = (tmp + C(j-, bit[d-]-) * v[j] % mod * sum[max(bit[d], (LL)j + )]) % mod;
ans = (ans + tmp * fac[bit[d-]] % mod * fac[bit[d-]] % mod * fac[n-bit[d]] % mod
* % mod * bit[k-d]) % mod;
}
ans = ans * inv_fac[n] % mod;
cout << ans << endl;
return ;
}

DAY 5模拟赛的更多相关文章

  1. NOIP模拟赛20161022

    NOIP模拟赛2016-10-22 题目名 东风谷早苗 西行寺幽幽子 琪露诺 上白泽慧音 源文件 robot.cpp/c/pas spring.cpp/c/pas iceroad.cpp/c/pas ...

  2. NOI模拟赛 Day1

    [考完试不想说话系列] 他们都会做呢QAQ 我毛线也不会呢QAQ 悲伤ING 考试问题: 1.感觉不是很清醒,有点困╯﹏╰ 2.为啥总不按照计划来!!! 3.脑洞在哪里 4.把模拟赛当作真正的比赛,紧 ...

  3. NOIP第7场模拟赛题解

    NOIP模拟赛第7场题解: 题解见:http://www.cqoi.net:2012/JudgeOnline/problemset.php?page=13 题号为2221-2224. 1.car 边界 ...

  4. contesthunter暑假NOIP模拟赛第一场题解

    contesthunter暑假NOIP模拟赛#1题解: 第一题:杯具大派送 水题.枚举A,B的公约数即可. #include <algorithm> #include <cmath& ...

  5. NOIP模拟赛 by hzwer

    2015年10月04日NOIP模拟赛 by hzwer    (这是小奇=> 小奇挖矿2(mining) [题目背景] 小奇飞船的钻头开启了无限耐久+精准采集模式!这次它要将原矿运到泛光之源的矿 ...

  6. 小奇模拟赛9.13 by hzwer

    2015年9月13日NOIP模拟赛 by hzwer    (这是小奇=> 小奇挖矿(explo) [题目背景] 小奇要开采一些矿物,它驾驶着一台带有钻头(初始能力值w)的飞船,按既定路线依次飞 ...

  7. PKUSC 模拟赛 day1 下午总结

    下午到了机房之后又困又饿,还要被强行摁着看英文题,简直差评 第一题是NOIP模拟赛的原题,随便模拟就好啦 本人模拟功力太渣不小心打错了个变量,居然调了40多分钟QAQ #include<cstd ...

  8. [GRYZ]寒假模拟赛

    写在前面 这是首次广饶一中的OIERS自编自导,自出自做(zuo)的模拟赛. 鉴于水平气压比较低,机(wei)智(suo)的WMY/XYD/HYXZC就上网FQ下海找了不少水(fei)题,经过他们优( ...

  9. BZOJ2741: 【FOTILE模拟赛】L

    2741: [FOTILE模拟赛]L Time Limit: 15 Sec  Memory Limit: 162 MBSubmit: 1170  Solved: 303[Submit][Status] ...

  10. 大家AK杯 灰天飞雁NOIP模拟赛题解/数据/标程

    数据 http://files.cnblogs.com/htfy/data.zip 简要题解 桌球碰撞 纯模拟,注意一开始就在袋口和v=0的情况.v和坐标可以是小数.为保险起见最好用extended/ ...

随机推荐

  1. 给定一个字符串,根据字符出现频率排序--Java实现

    题目描述: 给定一个字符串,请将字符串里的字符按照出现的频率降序排列. 示例 1: 输入:"tree" 输出:"eert" 解释:'e'出现两次,'r'和't' ...

  2. python3.7 利用pyhive 连接上hive(亲测可用)

    来python爬虫中,经常会遇到数据的存储问题,如果有大量数据,hive存储是个不错的选择. 那么python如何来连接hive呢?网上有各种教程但是都不是很好用,亲自测试pyhive可用 要求:可用 ...

  3. C# 过滤字典中的数据 并将过滤后的数据转成新的字典对象

    Dictionary<string, object> dic = new Dictionary<string, object>(); dic.Add("); dic. ...

  4. Codeforces Round #581 (Div. 2) C. Anna, Svyatoslav and Maps (Floyd 算法,最短路)

    C. Anna, Svyatoslav and Maps time limit per test2 seconds memory limit per test256 megabytes inputst ...

  5. uestc summer training #4 牛客第一场

    A dp[i][j][k]可以n3地做 但是正解是找把问题转化为一个两点不相交路径 最终答案为C(n+m, n)2-C(n+m, m-1)C(n+m,n-1) B 把题目的矩阵看成无向图的邻接矩阵 这 ...

  6. Elasticsearch改动

    随着Elasticsearch的版本升级,Elasticsearch的一些特性也在改变,下面是一些需要注意的地方 v6.x 版本之前 : 一个index下面是可以创建多个type v6.x 版本 : ...

  7. arm开发板make编译时遇到 make[2]:*** [s-attrtab] 已杀死 问题的解决方案

    未验证 出现“make[2]: *** [s-attrtab] 已杀死”log 是由于内存不足 解决方案 增加swapfile 步骤如下: 1. 查看当前swapfile状态 root@ubuntu: ...

  8. HDU - 6583 Typewriter (后缀自动机+dp)

    题目链接 题意:你要打印一段字符串,往尾部添加一个字符需要花费p元,复制一段字符到尾部需要花费q元,求打印完全部字符的最小花费. 一开始想的贪心,后来发现忘了考虑p<q的情况了,还纳闷怎么不对. ...

  9. String中的intern方法

    上一篇你真的会用String吗(3)-关于字符串拼接中我们提到了String.intern()方法,本篇我们就来详细的看下这个方法是干嘛的.首先来看下jdk8中这个方法的注释: When the in ...

  10. Spring mvc i18n国际化的简单demo

    在渲染视图的xml文件中,配置一个i18nBean 实现两个接口: SessionLocaleResolver --> 加载资源主题 ReloadableResourceBundleMessag ...