__int128(例题:2020牛客多校第八场K题)

题意:

有n道菜,第i道菜的利润为\(a_i\),且有\(b_i\)盘。你要按照下列要求给顾客上菜。

1.每位顾客至少有一道菜

2.给顾客上菜时,都必须从第一道菜开始,上连续的编号的菜,例如,你可能给一位顾客 上的菜为第一道,第二道,第三道,但是不能为只上第二道而不上第一道,或者第一道,第三道中间缺少第二道。

求这些菜能够容纳的最大顾客数,并且求出在容纳最多顾客时的利润最大为多少。

数据范围

\(1\le n\le 10^{5}\),\(-10^{9}\le a_i\le10^{9}\)​,\(1\le b_i\le10^{5}\)

输入

  1. 2
  2. 3
  3. 2 -1 3
  4. 3 2 1
  5. 4
  6. 3 -2 3 -1
  7. 4 2 1 2

输出

  1. Case #1: 3 8
  2. Case #2: 4 13

说明

对于测试案例1,最大访问者数量为3,一种可能的解决方案是:

第一位访客获得食物1,利润是2。

第二位访客获得食物1,利润为2。

第三位访客获得食物1 +食物2 +食物3,利润为2 +(-1)+ 3。

题解

1.由于必须上第一道菜,因此第一道菜的数量即为最大招待顾客的数量。

2.计算最大利润时,采用贪心策略,在满足条件时,优先选取利润最大的即可,由于每次选取 1~i的连续的菜,可以先求出前i份菜的利润的前缀和。然后按利润前缀和大小排序,从大到小遍历,对于前n份菜利润为sum的贡献计算方法为,求出前n种菜剩余的菜的最小的数量 min,让答案累加\(min*sum\),然后将前n种菜的数量都减去min,这个操作可以用线段树来进行区间查询和修改。

3.由于答案最大值为 \(10^{19}\),稍微超过了long long int的范围,因此c++要采用 __int128,__int128为128位的整数,是gcc的扩展,大小范围在 [\(2^{127},2^{127}-1\)].且在windows环境下的gcc不支持编译,在linux环境下的gcc支持编译,不过没有对应的输入输出函数,要自定义输入输出函数。

__int128模板

  1. `inline __int128 read(){//读入
  2. __int128 x=0,f=1;
  3. char ch=getchar();
  4. while(ch<'0'||ch>'9'){
  5. ​ if(ch=='-')
  6. ​ f=-1;
  7. ​ ch=getchar();
  8. }
  9. while(ch>='0'&&ch<='9')
  10. ​ x=x*10+ch-'0';
  11. ​ ch=getchar();
  12. }
  13. return x*f;
  14. }
  15. inline void fprint(__int128 x){//输出。
  16. if(x<0){
  17. ​ putchar('-');
  18. ​ x=-x;
  19. }
  20. if(x>9)
  21. ​ fprint(x/10);
  22. putchar(x%10+'0');
  23. }`

题目完整code

  1. #include<bits/stdc++.h>
  2. #define scd(x) scanf("%d",&x)
  3. #define scdd(x,y) scanf("%d%d",&x,&y)
  4. #define sclld(x) scanf("%lld",&x)
  5. #define sclldd(x,y) scanf("%lld%lld",&x,&y)
  6. #define print(x) cout<<x<<endl
  7. #define CLR(a) memset(a,0,sizeof(a))
  8. #define ls (rt<<1)
  9. #define rs (rt<<1|1)
  10. using namespace std;
  11. typedef long long ll;
  12. typedef double db;
  13. const double eps = 1e-7;
  14. const double pi = acos(-1.0);
  15. const int inf = 0x3f3f3f3f;
  16. const ll linf = 0x3f3f3f3f3f3f3f3f;
  17. const ll mod = ll(1e9)+7;
  18. const int maxn=int(2e5)+500;
  19. template<typename tp>inline tp lowbit(tp x){return x&(-x);}
  20. template<typename tp_>void debug(tp_ x) {cout<<"*********** "<<x<<" *************"<<endl;}
  21. template<typename tp1_,typename tp2_>void debug(tp1_ x,tp2_ y){cout<<"*********** "<<x<<" "<<y<<" *************"<<endl;}
  22. struct P{int x;__int128 y;P(){}P(int _x,__int128 _y):x(_x),y(_y){}};
  23. bool cmp(const P elem1,const P elem2){
  24. if(elem1.y==elem2.y)return elem1.x>elem2.x;
  25. return elem1.y<elem2.y;
  26. }
  27. __int128 a[maxn];
  28. __int128 b[maxn];
  29. P sum[maxn];
  30. int Case = 1;
  31. struct node{
  32. __int128 sum;
  33. __int128 lazy;
  34. }tree[maxn<<2];
  35. inline __int128 read(){
  36. __int128 x=0,f=1;
  37. char ch=getchar();
  38. while(ch<'0'||ch>'9'){
  39. if(ch=='-')
  40. f=-1;
  41. ch=getchar();
  42. }
  43. while(ch>='0'&&ch<='9'){
  44. x=x*10+ch-'0';
  45. ch=getchar();
  46. }
  47. return x*f;
  48. }
  49. inline void fprint(__int128 x){
  50. if(x<0){
  51. putchar('-');
  52. x=-x;
  53. }
  54. if(x>9)
  55. fprint(x/10);
  56. putchar(x%10+'0');
  57. }
  58. void build(int rt,int l,int r){
  59. tree[rt].sum=tree[rt].lazy=0;
  60. if(l==r){
  61. tree[rt].sum = b[l];
  62. return ;
  63. }
  64. int mid = (l+r)>>1;
  65. build(ls,l,mid);
  66. build(rs,mid+1,r);
  67. tree[rt].sum = min(tree[ls].sum,tree[rs].sum);
  68. }
  69. void pushdown(int rt,int l,int r){
  70. if(tree[rt].lazy){
  71. __int128 val = tree[rt].lazy;
  72. tree[ls].sum-=val;
  73. tree[rs].sum-=val;
  74. tree[ls].lazy += val;
  75. tree[rs].lazy += val;
  76. tree[rt].lazy = 0;
  77. }
  78. }
  79. void update(int rt,int l,int r,int L,int R,__int128 val){
  80. if(l>=L&&r<=R){
  81. tree[rt].sum -=val;
  82. tree[rt].lazy += val;
  83. return ;
  84. }
  85. pushdown(rt,l,r);
  86. int mid= (l+r)>>1;
  87. if(L<=mid)update(ls,l,mid,L,R,val);
  88. if(R>mid)update(rs,mid+1,r,L,R,val);
  89. tree[rt].sum = min(tree[ls].sum,tree[rs].sum);
  90. }
  91. __int128 ask(int rt,int l,int r,int L,int R){
  92. if(l>=L&&r<=R){
  93. return tree[rt].sum;
  94. }
  95. pushdown(rt,l,r);
  96. int mid = (l+r)>>1;
  97. __int128 res = inf;
  98. if(L<=mid)res=min(res,ask(ls,l,mid,L,R));
  99. if(R>mid)res=min(res,ask(rs,mid+1,r,L,R));
  100. return res;
  101. }
  102. void solve() {
  103. int n;
  104. scd(n);
  105. sum[0].y = 0;
  106. for(int i=1;i<=n;i++){
  107. a[i]=read();
  108. sum[i].x=i;
  109. sum[i].y=a[i]+sum[i-1].y;
  110. }
  111. for(int i=1;i<=n;i++)b[i]=read();
  112. sort(sum+1,sum+n+1,cmp);
  113. __int128 visit = b[1];
  114. build(1,1,n);
  115. __int128 ans = 0;
  116. for(int i=n;i>=1;i--){
  117. __int128 cnt = ask(1,1,n,1,sum[i].x);
  118. ans+= cnt*sum[i].y;
  119. update(1,1,n,1,sum[i].x,cnt);
  120. }
  121. printf("Case #%d: ",Case);
  122. fprint(visit);
  123. printf(" ");
  124. fprint(ans);
  125. printf("\n");
  126. }
  127. void Main(){
  128. int _;
  129. scd(_);
  130. while(_--)
  131. solve(),++Case;
  132. }
  133. //#define _Debug
  134. int main(){
  135. #ifdef _Debug
  136. freopen("data.in","r",stdin);
  137. clock_t b = clock();
  138. Main();
  139. clock_t e = clock();
  140. cout<<"the time of cost is "<<(e-b)<<endl;
  141. #else
  142. Main();
  143. #endif
  144. return 0;
  145. }

2020牛客多校第八场K题的更多相关文章

  1. 2019牛客多校第八场 F题 Flowers 计算几何+线段树

    2019牛客多校第八场 F题 Flowers 先枚举出三角形内部的点D. 下面所说的旋转没有指明逆时针还是顺时针则是指逆时针旋转. 固定内部点的答案的获取 anti(A)anti(A)anti(A)或 ...

  2. Distance(2019年牛客多校第八场D题+CDQ+树状数组)

    题目链接 传送门 思路 这个题在\(BZOJ\)上有个二维平面的版本(\(BZOJ2716\)天使玩偶),不过是权限题因此就不附带链接了,我也只是在算法进阶指南上看到过,那个题的写法是\(CDQ\), ...

  3. Explorer(2019年牛客多校第八场E题+线段树+可撤销并查集)

    题目链接 传送门 题意 给你一张无向图,每条边\(u_i,v_i\)的权值范围为\([L_i,R_i]\),要经过这条边的条件是你的容量要在\([L_i,R_i]\),现在问你你有多少种容量使得你可以 ...

  4. 2019牛客多校第四场 I题 后缀自动机_后缀数组_求两个串de公共子串的种类数

    目录 求若干个串的公共子串个数相关变形题 对一个串建后缀自动机,另一个串在上面跑同时计数 广义后缀自动机 后缀数组 其他:POJ 3415 求两个串长度至少为k的公共子串数量 @(牛客多校第四场 I题 ...

  5. 暴力三维树状数组求曼哈顿距离求最值——牛客多校第八场D

    涉及的知识点挺多,但是大多是套路 1.求曼哈顿距离的最值一般对所有情况进行讨论 2.三维树状数组用来求前缀最大值 /* 有一个三维坐标系(x,y,z),取值范围为[1,n],[1,m],[1,h],有 ...

  6. 线段树区间离散化维护按秩合并并查集(可撤销)——牛客多校第八场E

    模板题..去网上学了可撤销的并查集.. /* 给定一个无向图,边的属性为(u,v,l,r),表示<u,v>可以通过的size为[l,r] 求出有多少不同的size可以从1->n 把每 ...

  7. 单调栈(最大子矩形强化版)——牛客多校第八场A

    求01矩阵里有多少个不同的1矩阵 首先预处理出pre[i][j]表示i上面连续的1个数,对每行的高度进行单调栈处理 栈里的元素维护两个值:pre[i][j]和向前延伸最多能维护的位置pos 然后算贡献 ...

  8. 牛客多校第八场 G Gemstones 栈/贪心

    题意: 对于一个序列,把可以把连着三个相同的字母拿走,问最多拿走多少组. 题解: 直接模拟栈,三个栈顶元素相同则答案+1,并弹出栈 #include<bits/stdc++.h> usin ...

  9. 牛客多校第八场 C CDMA 线性代数:沃尔什矩阵

    题意: 构造出一个由1和-1组成的$2^k*2^k$的矩阵,使得矩阵任意两列内积为0 题解: 数学知识,沃尔什矩阵.沃尔什矩阵的特性被CDMA(码分多址)采用,使得编码成为无线信号的频段和振幅之外的第 ...

随机推荐

  1. php批量 下载图片

    <?php set_time_limit(0); $file = fopen("index.csv",'r');$temp = [];$i=0;$firstsku='';wh ...

  2. 最新MySQL入门篇

    一.SQL简介 ​ SQL:结构化查询语言(Structured Query Language),是一种特殊目的的编程语言,是一种数据库查询和程序设计语言,用于存取数据以及查询.更新和管理关系数据库系 ...

  3. python 爬虫:HTTP ERROR 406

    解决方法: 设置了Accept头后解决了,但是还是不知道原因 headers:{ Accept:"text/html, application/xhtml+xml, */*" }原 ...

  4. java 数据结构(十二):Collections工具类的使用

    Collections工具类1.作用:操作Collection和Map的工具类 2.常用方法:reverse(List):反转 List 中元素的顺序shuffle(List):对 List 集合元素 ...

  5. python 并发专题(九):基础部分补充(一)进程

    概念 串行:所有的任务一个一个的完成. 并发:一个cpu完成多个任务.看起来像是同时完成. 并行:多个cpu执行多个任务,真正的同时完成. 阻塞:cpu遇到IO就是阻塞. 非阻塞:没有IO,就叫非阻塞 ...

  6. python 面向对象专题(五):私有成员、类方法、静态方法、属性、isinstance/issubclass

    https://www.cnblogs.com/liubing8/p/11325421.html 目录 Python面向对象05 /私有成员.类方法.静态方法.属性.isinstance/issubc ...

  7. Git操作(二)

    很久以前写的git入门,最近又巩固了一下Git分支操作,下面是我的一些整理. 1.分支与合并 #创建并切换到该分支 git checkout -b xxx #查看当前分支 git branch #进行 ...

  8. Websphere修改web.xml不生效的解决办法(转)

    在websphere下部署了一个java工程后,如果修改了web.xml文件,重新启动这个java工程发现websphere并没有自动加载web.xml文件,即修改后的web.xml并不起作用,除非重 ...

  9. web自动化测试实战之批量执行测试用例

    01实战之分离测试固件 在UI 自动化测试中,不管编写哪个模块的测试用例,都需要首先在测试类中编写测试固件初始化WebDriver类及打开浏览器,执行登录,才能进行下一步业务逻辑的操作,测试用例执行完 ...

  10. 记录一次升级ant-design-vue的遇见的bug

    记录一次升级ant-design-vue的遇见的bug 使用版本: "version": "2.5.2" "ant-design-vue": ...