[NOIP模拟][简单] T1–举办比赛
border="0" width="330" height="86" src="//music.163.com/outchain/player?type=2&id=453927842&auto=1&height=66">阅读本文推荐BGM :너를 보네 (看到你了) - 박별
题目描述 :
Mstdream 举办了一场抢答比赛!
这场抢答比赛有 n 支队伍参赛,第 i 支队伍将会被分配一个随机值 si, 每一个问题, si 值较小的队伍会拥有优先发言权, 于是 Mstdream 想知道所有队伍最小的 si 值, 以便统计 。
但是,由于各种各样的原因,一些队伍的 si值会变化,Mstdream想让你帮忙,对于每次修改后求出所有队伍中最小的 si 值 。
由于队伍实在太多了!我们将采用数据生成的方式读入数据
我们将给出n, m, x0, x1, a, b, c七个数,对于 c++ 语言,我们将采用如下读入 :
#define uint unsigned int
uint x0, x1, a, b, c, n, m;
uint now = 1, tot = 0;
uint s[10000010];
uint nxt(){
uint t = x0 * a + x1 * b + c;
x0 = x1;
x1 = t;
return x0 >> 2;
}
int main(){
std::cin>>n>>m>>x0>>x1>>a>>b>>c;
for(int i = 0; i < n; ++i){
s[i] = 2147483647;
}
for(int i = 1; i <= m; ++i){
int f = nxt();
int g = nxt();
int ps = f % n;
s[ps] = g; //此处是修改
uint ans = 0;
//......此处需要你求出 s[0] 到 s[n-1] 的最小值, 并且存在 ans 当中
now *= 10099;
tot += now*ans;
}
std::cout<<tot<<std::endl;
}
根据相关理论, nxt()函数是随机的。
Input
7个数n,m,x0,x1,a,b,c
Output
一个数,即程序中的tot值
Sample Input
5 5 1 2 3 4 5
Sample Output
3818396440
Sample Input
10000000 10000000 555 888 777 666 12345
Sample Output
4134418848
范围 :
10% n, m <= 1000
40% n, m <= 100000
100% n <= 10000000, m <= 50000000
保证 x0, x1, a, b, c 在 unsigned int 范围内Time Limit: 4 Sec
Memory Limit: 512 MB
谈一谈我的想法:
初看这道题, 哦,求最小值带修改,那直接线段树啊。咦,等等,范围 5e7,这怎么办,不管了先打一通,果然线段树果然爆栈,完了完了我要爆在第一题了,讲真说好的可以AK呢,但是这么着急也不是办法, 冷静下来再看一看题,咦,等等, nxt 函数随机啊(虽然是规则的随机), 再算了算期望不大啊,好像可以暴力搞啊。于是打了打,大样例只有 1.09 Sec 很友善啊, 最后评测的时候虽然慢了一点,但还是过了。
简单理一下 :
这道题呢时限开得很大, 给你一个小小的暗示: 暴力, 记录当前序列中的最小值,简单维护: 如果当次操作改变的正好是当前的最小值,就对整个序列从头到尾扫一遍,维护最小,如果不是修改的当前最小值, 就直接与当前最小值比较维护最小, 完了!!
考虑期望对于每次操作选择序列中随机的一个数, 操作一共 5e7 次, 期望选中同一个数为 m / n = 5, 所以不会 T 掉。
下面贴出代码
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <string>
#include <algorithm>
#include <iostream>
#include <cmath>
#include <ctime>
#include <map>
#include <vector>
#define uint unsigned int
using namespace std;
uint x0, x1, a, b, n, m, c;
uint now = 1, tot = 0;
uint s1[10000010];
uint nxt() {
uint t = x0 * a + x1 * b + c;
x0 = x1;
x1 = t;
return x0 >> 2;
}
int main() {
cin>>n>>m>>x0>>x1>>a>>b>>c;
for(int i = 0; i < n; ++i) s1[i]= 2147483647;
int o = 0;
for(int i = 1; i <= m; ++i) {
int f = nxt();
int g = nxt();
int ps = f % n;
s1[ps] = g;
uint ans = 0;
if(o == ps) {
uint now = 0x3f3f3f3f;
for(int i = 0; i < n; ++i) {
if(now > s1[i])
now = s1[i], o = i;
}
}
else
if(s1[ps] < s1[o]) o = ps;
ans = s1[o];
now *= 10099;
tot += now * ans;
}
cout<<tot;
}
本题结束
border="0" width="330" height="86" src="//music.163.com/outchain/player?type=2&id=4195988&auto=0&height=66">
是不是要犒劳自己一曲音乐呢:Still Worth Fighting For - My Darkest Days
感谢阅读本篇文章,喜欢的话,点个赞吧,你的鼓励就是我最大的动力