[关闭]
@xiaoziyao 2021-05-05T08:23:58.000000Z 字数 1387 阅读 1139

CF1515I Phoenix and Diamonds解题报告

解题报告


CF1515I Phoenix and Diamonds解题报告:

更好的阅读体验

似乎是你谷首杀,针不戳。

题意

种钻石,一颗第种钻石重量为,价值为,一开始第中钻石的库存为。接下来进行次操作:

分析

神奇的题目,感觉没有CF*3400评分这么夸张,不过这数据确实强。

由于钻石种类已经给定,因此我们可以知道拿钻石的优先级。

发现处理询问的复杂度与总得有点关系,看的数据范围就大胆猜想复杂度要带,那么考虑如何每次至少把除二。

的最高位为,对于第位,设一个钻石是“轻的”当且仅当其重量小于,否则如果它的重量小于,那么它是“重的”,一个很显然的结论就是在最高位不变的情况下不能取多于一个“重的”钻石。

自然而然地设表示对于第位,“轻的”钻石价值和与重量和,表示对于第位,“轻的”钻石重量加上一个最小的“重的”钻石的重量之和。

状态是的,不好存储,考虑上线段树,将上面的区间改为其对应线段树上的结点,那么很容易写出一个来动态维护这三个数组。

查询部分,我们就先判掉叶子结点的情况,然后考虑重钻石与轻钻石都可以取走的情况,然后再判一判是不是只能取轻钻石,如果都不是的话就递归两个儿子处理。

记得动态维护当前的最高位

时间复杂度:。(复杂度不太会证/kel)

  1. long long query(int l,int r,int now){//calc()是维护c的最高位ω的函数
  2. if(l==r){
  3. long long num=min(a[id[l]],c/w[id[l]]);
  4. c-=num*w[id[l]],calc();
  5. return num*v[id[l]];
  6. }
  7. if(lightw[now][omega]<=c){
  8. long long res=lightv[now][omega];
  9. c-=lightw[now][omega],calc();
  10. return res;
  11. }
  12. if(lightw[now][omega-1]<=c&&c<extra[now][omega-1]){
  13. long long res=lightv[now][omega-1];
  14. c-=lightw[now][omega-1],calc();
  15. return res;
  16. }
  17. int mid=(l+r)>>1;
  18. return query(l,mid,lc[now])+query(mid+1,r,rc[now]);
  19. }

AC记录&代码

添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注