Codeforces 626G - Raffles(贪心+堆)
考虑对于固定的彩票池 \(i\),我们假设现在押了 \(x\) 张彩票。利用差分的思想,从 \(x\) 张彩票变为 \(x+1\) 张时,期望的变化量 \(\Delta E=\dfrac{p_i(x+1)}{l_i+x+1}-\dfrac{p_ix}{l_i+x}=\dfrac{p_il_i}{(l_i+x+1)(l_i+x)}\)。容易发现该函数为关于 \(x\) 的减函数,所以考虑直接贪心的做法:建一个堆 \(st\),维护所有彩票池由当前彩票数量变为当前彩票数量 \(+1\),期望的变化量,贪心 \(t\) 轮每次贪心地取出堆中最大的元素就行了。
接下来考虑有修改的情况:首先我们假设对于修改的元素 \(x\),\(x\) 彩票池押的彩票个数不变,也就是说我们重新计算一遍 \(x\) 彩票池押中的彩票价值的期望值。显然这样不一定是最优的,于是我们考虑再建一个堆 \(st_2\) 维护已经押入彩票池的彩票的价值,每次贪心地取出 \(st_2\) 中最小的元素并加入 \(st\) 中最大的元素(类似于反悔贪心),直到不能再操作为止即可。
由于每次操作只有加一和减一,所以最多只会引起一张彩票的变化,故复杂度是正确的。
#include <bits/stdc++.h>
using namespace std;
#define fi first
#define se second
#define fz(i,a,b) for(int i=a;i<=b;i++)
#define fd(i,a,b) for(int i=a;i>=b;i--)
#define ffe(it,v) for(__typeof(v.begin()) it=v.begin();it!=v.end();it++)
#define fill0(a) memset(a,0,sizeof(a))
#define fill1(a) memset(a,-1,sizeof(a))
#define fillbig(a) memset(a,63,sizeof(a))
#define pb push_back
#define ppb pop_back
#define mp make_pair
template<typename T1,typename T2> void chkmin(T1 &x,T2 y){if(x>y) x=y;}
template<typename T1,typename T2> void chkmax(T1 &x,T2 y){if(x<y) x=y;}
typedef pair<int,int> pii;
typedef long long ll;
template<typename T> void read(T &x){
x=0;char c=getchar();T neg=1;
while(!isdigit(c)){if(c=='-') neg=-1;c=getchar();}
while(isdigit(c)) x=x*10+c-'0',c=getchar();
x*=neg;
}
const int MAXN=2e5;
const double EPS=1e-10;
const double INF=1e18;
const int MAGIC=15;
int n,t,qu,p[MAXN+5],l[MAXN+5],c[MAXN+5];
double dif(int x,int c){
if(!c) return INF;if(c>l[x]) return 0;
return 1.0*p[x]*l[x]/(c+l[x])/(c-1+l[x]);
}
struct node{
double val;int x,y;
node(int _x=0,int _y=0){val=dif(_x,_y);x=_x;y=_y;}
bool operator <(const node &rhs) const{
return (fabs(val-rhs.val)>EPS)?(val<rhs.val):(x<rhs.x);
}
};
double ans=0;
set<node> nw,cur;
void ins(){
node t=*nw.rbegin();int x=t.x;//assert(fabs(t.val-dif(x,c[x]+1))<EPS);
nw.erase(nw.find(node(x,c[x]+1)));cur.erase(cur.find(node(x,c[x])));
ans+=t.val;c[x]++;
nw.insert(node(x,c[x]+1));cur.insert(node(x,c[x]));
}
void del(){
node t=*cur.begin();int x=t.x;//assert(fabs(t.val-dif(x,c[x]))<EPS);
nw.erase(nw.find(node(x,c[x]+1)));cur.erase(cur.find(node(x,c[x])));
ans-=t.val;c[x]--;
nw.insert(node(x,c[x]+1));cur.insert(node(x,c[x]));
}
int main(){
scanf("%d%d%d",&n,&t,&qu);
for(int i=1;i<=n;i++) scanf("%d",&p[i]);
for(int i=1;i<=n;i++) scanf("%d",&l[i]);
for(int i=1;i<=n;i++) nw.insert(node(i,c[i]+1)),cur.insert(node(i,c[i]));
for(int i=1;i<=t;i++) ins();
while(qu--){
int opt,x;scanf("%d%d",&opt,&x);
// assert(cur.find(node(x,c[x]))!=cur.end());
nw.erase(nw.find(node(x,c[x]+1)));cur.erase(cur.find(node(x,c[x])));
ans-=1.0*p[x]*min(c[x],l[x])/(l[x]+min(c[x],l[x]));
l[x]+=((opt==1)?(1):(-1));
nw.insert(node(x,c[x]+1));cur.insert(node(x,c[x]));
ans+=1.0*p[x]*min(c[x],l[x])/(l[x]+min(c[x],l[x]));
for(int i=1;i<=MAGIC;i++) del(),ins();
printf("%.15lf\n",ans);
}
return 0;
}
Codeforces 626G - Raffles(贪心+堆)的更多相关文章
- Codeforces 626G Raffles(贪心+线段树)
G. Raffles time limit per test:5 seconds memory limit per test:256 megabytes input:standard input ou ...
- Codeforces 626G Raffles 【贪心】【线段树】
题意: 给n个奖池,t张彩票,q次操作. 每个奖池的奖金为pi. 每个奖池现有的彩票的数量为ai,保证ai>=1: q次操作,每次有两种,第i个奖池的现有彩票数量加一,或减一. 不允许投票的数量 ...
- 【贪心+堆】XMU 1584 小明的烦恼
题目链接: http://acm.xmu.edu.cn/JudgeOnline/problem.php?id=1584 题目大意: 给n(n<=100 000)个任务的耗时和截至时间,问最少不能 ...
- BZOJ_2151_种树_贪心+堆+链表
BZOJ_2151_种树_贪心+堆 Description A城市有一个巨大的圆形广场,为了绿化环境和净化空气,市政府决定沿圆形广场外圈种一圈树.园林部门得到指令后,初步规划出n个种树的位置,顺时针编 ...
- BZOJ_2006_[NOI2010]超级钢琴_贪心+堆+ST表
BZOJ_2006_[NOI2010]超级钢琴_贪心+堆+ST表 Description 小Z是一个小有名气的钢琴家,最近C博士送给了小Z一架超级钢琴,小Z希望能够用这架钢琴创作出世界上最美妙的 音乐 ...
- BZOJ_1029_ [JSOI2007]建筑抢修_贪心+堆
BZOJ_1029_ [JSOI2007]建筑抢修_贪心+堆 Description 小刚在玩JSOI提供的一个称之为“建筑抢修”的电脑游戏:经过了一场激烈的战斗,T部落消灭了所有z部落的入侵者.但是 ...
- 【bzoj4425】[Nwerc2015]Assigning Workstations分配工作站 贪心+堆
题目描述 佩内洛普是新建立的超级计算机的管理员中的一员. 她的工作是分配工作站给到这里来运行他们的计算研究任务的研究人员. 佩内洛普非常懒惰,不喜欢为到达的研究者们解锁机器. 她可以从在她的办公桌远程 ...
- 【bzoj1029】[JSOI2007]建筑抢修 贪心+堆
题目描述 小刚在玩JSOI提供的一个称之为“建筑抢修”的电脑游戏:经过了一场激烈的战斗,T部落消灭了所有z部落的入侵者.但是T部落的基地里已经有N个建筑设施受到了严重的损伤,如果不尽快修复的话,这些建 ...
- CodeForces - 158B.Taxi (贪心)
CodeForces - 158B.Taxi (贪心) 题意分析 首先对1234的个数分别统计,4人组的直接加上即可.然后让1和3成对处理,只有2种情况,第一种是1多,就让剩下的1和2组队处理,另外一 ...
随机推荐
- 虚拟机研究系列-「GC本质底层机制」SafePoint的深入分析和底层原理探究指南
SafePoint前提介绍 在高度优化的现代JVM里,Safepoint有几种不同的用法.GC safepoint是最常见.大家听说得最多的,但还有deoptimization safepoint也很 ...
- BUAA_2020_软件工程_提问回顾与总结
项目 内容 这个作业属于哪个课程 2020春季计算机学院软件工程(罗杰 任建) 这个作业的要求在哪里 提问回顾与总结作业要求 我在这个课程的目标 了解软件工程的技术,掌握工程化开发的能力 这个作业在哪 ...
- pwn200,一道不完全考察ret2libc的小小pwn题
pwn200 ---XDCTF-2015 每日一pwn,今天又做了一个pwn,那个pwn呢???攻防世界的进阶区里的一道小pwn题,虽然这个题考察的知识不多,rop链也比较好构建,但是还是让我又学到了 ...
- AFO记
希望永远也不要动笔写这个. 发以自勉
- sort命令的学习与实践
一.用man sort 查看sort的帮助文档 *sort将文件的每一行作为一个单位,相互比较,比较原则是从首字符向后,依次按ASCII码值进行比较,最后将他们按升序输出. [rocrocket@ro ...
- cf22A Second Order Statistics(STL-UNIQUE的使用)
题意: N个数,找出第二大的数.如果没有输出-1. 思路: UNIQUE的使用. 代码: int a[105]; int n; int main(){ cin>>n; rep(i,0,n- ...
- diff 命令,防止遗忘
常规输出: diff 1.file 2.file 并排格式输出: diff 1.file 2.file -y -W 50 显示说明 "|"表示前后2个文件内容有不同 "& ...
- CSS学习(二)选择符
元素选择符:以元素名作为选择符(span{ color: red; }) 群组选择符:将两个选择符用逗号隔开构成群组(span, div{ color: red; }) 通用选择符:通用选择符(*)将 ...
- sudo 命令详解
在linux系统中,由于root的权限过大,一般情况都不使用它.只有在一些特殊情况下才采用登录root执行管理任务,一般情况下临时使用root权限多采用su和sudo命令. 一.su和sudo命令对比 ...
- vue脚手架配置代理
vue.config.js配置具体代理规则 module.exports = { devServer: { proxy: { '/api1': { // 匹配所有以 '/api1'开头的请求路径 ta ...