Codeforces 521D - Shop(贪心)
一道不算太难的贪心,可惜又没自己想出来,显然省选之后我的能力呈 \(y=-1145141919810192608179998244353x+c\) 的趋势下滑,其中 \(c\) 为我省选前的能力(
首先假设我们已经选出了这 \(k\) 个操作,考虑按照怎样的顺序执行这些操作,显然我们会先执行赋值操作,再加法操作,最后乘法操作,因为赋值操作早晚都是要进行的,按照贪心的思想显然在一开始就进行赋值操作最优,而对于序列中某个元素 \(x\),我们假设它需进行 \(+y,\times z\) 两个操作,那么先加后乘的结果为 \(z(x+y)\),先乘后加的结果为 \(xz+y\),做差可得 \(\Delta=y(z-1)\ge 0\),故先加后乘必然比先乘后加来得更优。
接下来考虑怎样选出这些操作。首先很明显对于一个 \(\times z\) 的操作,不管它作用在哪个数上,都会导致最后的结果也乘 \(z\),也就是说如果只有乘法操作的话,我们可以直接将 \(z\) 从大到小排序贪心。那加上加法和赋值操作该怎么办呢?有一件很显然的事情是赋值操作可以转化为加法操作,因为显然每个数最多被赋一次值,并且给下标为 \(i\) 的元素赋的值只可能是所有作用在 \(i\) 的赋值操作中值最大的,假设为 \(x_i\),那么我们就可以将作用在 \(i\) 上的赋值操作看作一次 \(+(x_i-a_i)\) 的加法操作。这样就只有加法操作了,我们还可以发现,对于加法操作我们肯定会按加的值从大到小选择,也就是说对于一次作用在 \(i\) 上的加法操作 \(+v\),假如我们执行了这次操作,那么在此次操作前 \(a_i\) 的值必然是一个定值,也就是说我们也可以将这次操作看作 \(\times\dfrac{a_i+v}{a_i}\)。这样所有加法、赋值操作都可以转化为乘法操作,也就可以按照最一开始的贪心策略贪了,时间复杂度 \(n\log n\)。
这里有一个小的注意点,就是我们由加法转化来的乘法操作会出现分数,此时我们就要对分数比较大小,而这题分数的分子分母会达到 \(10^5\times 10^6=10^{11}\),直接比较大小运算量会达到 \(10^{11}\times 10^{11}=10^{22}\),爆 ll,如果我没记错的话这样写大概会 WA 146,这里有一个小技巧,就是所有分数值都减去 \(1\),这样 \(\times\dfrac{a_i+v}{a_i}\) 就变成了 \(\dfrac{v}{a_i}\),分子大小就降到了 \(10^{6}\),直接排就能过了。
const int MAXN=1e5;
int n,m,k,ini[MAXN+5],c1,c2,c3;
struct event{int opt,id,x;ll a,b;} q1[MAXN+5],q2[MAXN+5],q3[MAXN+5];
bool cmp1(event lhs,event rhs){return (lhs.x^rhs.x)?(lhs.x<rhs.x):(lhs.a<rhs.a);}
bool cmp2(event lhs,event rhs){return (lhs.x^rhs.x)?(lhs.x<rhs.x):(lhs.a>rhs.a);}
bool cmp3(event lhs,event rhs){return lhs.a*rhs.b>rhs.a*lhs.b;}
bool cmp4(event lhs,event rhs){return lhs.opt<rhs.opt;}
int main(){
scanf("%d%d%d",&n,&m,&k);
for(int i=1;i<=n;i++) scanf("%d",&ini[i]);
for(int i=1;i<=m;i++){
int opt,x,y;scanf("%d%d%d",&opt,&x,&y);
if(opt==1&&y>ini[x]) q1[++c1]={1,i,x,y,1};
else if(opt==2) q2[++c2]={2,i,x,y,1};
else if(opt==3) q3[++c3]={3,i,x,y,1};
} sort(q1+1,q1+c1+1,cmp1);
for(int i=1;i<=c1;i++) if(q1[i].x!=q1[i+1].x)
q2[++c2]={q1[i].opt,q1[i].id,q1[i].x,q1[i].a-ini[q1[i].x],1};
sort(q2+1,q2+c2+1,cmp2);ll sum=0;
for(int i=1;i<=c2;i++){
if(q2[i].x!=q2[i-1].x) sum=ini[q2[i].x];
q3[++c3]={q2[i].opt,q2[i].id,q2[i].x,sum+q2[i].a,sum};sum+=q2[i].a;
// printf("%d %d %d %lld\n",q2[i].opt,q2[i].id,q2[i].x,q2[i].a);
} for(int i=1;i<=c3;i++) q3[i].a-=q3[i].b;
sort(q3+1,q3+c3+1,cmp3);k=min(c3,k);
sort(q3+1,q3+k+1,cmp4);printf("%d\n",k);
for(int i=1;i<=k;i++) printf("%d ",q3[i].id);
return 0;
}
Codeforces 521D - Shop(贪心)的更多相关文章
- CodeForces - 158B.Taxi (贪心)
CodeForces - 158B.Taxi (贪心) 题意分析 首先对1234的个数分别统计,4人组的直接加上即可.然后让1和3成对处理,只有2种情况,第一种是1多,就让剩下的1和2组队处理,另外一 ...
- codeforces 724D(贪心)
题目链接:http://codeforces.com/contest/724/problem/D 题意:给定一个字符串和一个数字m,选取一个一个子序列s,使得对于字符串中任意长度为m的子序列都至少含有 ...
- Codeforces 626G Raffles(贪心+线段树)
G. Raffles time limit per test:5 seconds memory limit per test:256 megabytes input:standard input ou ...
- Cut 'em all! CodeForces - 982C(贪心dfs)
K - Cut 'em all! CodeForces - 982C 给一棵树 求最多能切几条边使剩下的子树都有偶数个节点 如果n是奇数 那么奇数=偶数+奇数 不管怎么切 都会有奇数 直接打印-1 贪 ...
- CodeForces - 940E - Cashback +贪心+DP
传送门:CodeForces - 940E - Cashback 题意:在一个长度为n的数组中,可以分出长度为 k 连续的多个数组b(每个数组 b 的 k 可不相同),然后,可以对每个数组 b 进行删 ...
- Codeforces 515C 题解(贪心+数论)(思维题)
题面 传送门:http://codeforces.com/problemset/problem/515/C Drazil is playing a math game with Varda. Let’ ...
- CodeForces 485C Bits[贪心 二进制]
C. Bits time limit per test1 second memory limit per test256 megabytes inputstandard input outputsta ...
- codeforces 732E(贪心)
题目链接:http://codeforces.com/contest/732/problem/E 题意:有n台计算机,m个插座,每台计算机有一个值a[i],每个插座有一个值b[i],每个插座最多只能对 ...
- Codeforces 732D [二分 ][贪心]
/* 不要低头,不要放弃,不要气馁,不要慌张 题意: n天进行m科考试,每科考试需要a的复习时间,n天每天最多可以考一科.并且指定哪天考哪科. 注意考试那天不能复习. 问最少需要多少天可全部通过考试. ...
随机推荐
- .Net2.0连接PG数据注意事项
.Net2.0连接PG数据注意事项 第一次用.net操作PG[.NET2.0] 一:Npgsql版本问题 1:如果是.net2.0 建议用2.0.11.0[NuGet搜索npgsql第一个的最低版本 ...
- Java:并发笔记-07
Java:并发笔记-07 说明:这是看了 bilibili 上 黑马程序员 的课程 java并发编程 后做的笔记 6. 共享模型之不可变 本章内容 不可变类的使用 不可变类设计 无状态类设计 6.1 ...
- [NOIP模拟46]鼠树
神仙题. 首先不考虑把黑点变白,发现每个白点的信息与它的归属点是相同的.可以在线段树中只维护黑点的信息,再记录$DFS$序上每个点之前黑点个数的前缀和,每次操作可以二分出该点的归属点进行操作. 具体维 ...
- 三极管和MOS管驱动电路的正确用法
1 三极管和MOS管的基本特性 三极管是电流控制电流器件,用基极电流的变化控制集电极电流的变化.有NPN型三极管(简称P型三极管)和PNP型三极管(简称N型三极管)两种,符号如下: MOS管是电压控制 ...
- X264编码测试验证
之前在做一个rtsp直播需求,其中一个方案是要用的x264来对摄像头数据进行实时编码推流,摄像头帧率是25fps,为了验证方案的可行性,先对x264的编码速度进行一个测试研究,再确认是否要采用此方案. ...
- (转载)linux chmod命令用法
chmod----改变一个或多个文件的存取模式(mode) chmod [options] mode files 只能文件属主或特权用户才能使用该功能来改变文件存取模式.mode可以是数字形式(八 ...
- hdu 2191 珍惜现在,感恩生活(多重背包)
题意: 有N元经费,M种大米,每种大米有单袋价格p元,单袋重量h,以及对应袋数c. 问最多可以买多重的大米. 思路: 经典多重背包,用二进制的方法. 看代码 代码: struct node{ int ...
- Vue3学习(十)之 页面、菜单、路由的使用
一.前言 好几天没更文了,周末真的太冷了,在家躺了一天不爱动.今天给暖气了,相对不那么冷了,就可以继续更文了. 由文章标题不难看出,就是实现点击菜单跳转的意思,我写的很直白了,哈哈. 二.实现点击菜单 ...
- 面试官问我JVM内存结构,我真的是
面试官:今天来聊聊JVM的内存结构吧? 候选者:嗯,好的 候选者:前几次面试的时候也提到了:class文件会被类加载器装载至JVM中,并且JVM会负责程序「运行时」的「内存管理」 候选者:而JVM的内 ...
- linux环境下redis安装(redis伪集群搭建)
redis在linux环境下搭建 1.创建目录 [root@192 local]# mkdir /usr/local/redis 2.下载redis,并解压 [root@192 local]# wge ...