__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}\)

输入

2
3
2 -1 3
3 2 1
4
3 -2 3 -1
4 2 1 2

输出

Case #1: 3 8
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模板

`inline __int128 read(){//读入

  __int128 x=0,f=1;

  char ch=getchar();

  while(ch<'0'||ch>'9'){

​    if(ch=='-')

​      f=-1;

​    ch=getchar();

  }
while(ch>='0'&&ch<='9') ​ x=x*10+ch-'0'; ​ ch=getchar(); } return x*f; } inline void fprint(__int128 x){//输出。 if(x<0){ ​ putchar('-'); ​ x=-x; } if(x>9) ​ fprint(x/10); putchar(x%10+'0'); }`

题目完整code

#include<bits/stdc++.h>
#define scd(x) scanf("%d",&x)
#define scdd(x,y) scanf("%d%d",&x,&y)
#define sclld(x) scanf("%lld",&x)
#define sclldd(x,y) scanf("%lld%lld",&x,&y)
#define print(x) cout<<x<<endl
#define CLR(a) memset(a,0,sizeof(a))
#define ls (rt<<1)
#define rs (rt<<1|1)
using namespace std;
typedef long long ll;
typedef double db;
const double eps = 1e-7;
const double pi = acos(-1.0);
const int inf = 0x3f3f3f3f;
const ll linf = 0x3f3f3f3f3f3f3f3f;
const ll mod = ll(1e9)+7;
const int maxn=int(2e5)+500;
template<typename tp>inline tp lowbit(tp x){return x&(-x);}
template<typename tp_>void debug(tp_ x) {cout<<"*********** "<<x<<" *************"<<endl;}
template<typename tp1_,typename tp2_>void debug(tp1_ x,tp2_ y){cout<<"*********** "<<x<<" "<<y<<" *************"<<endl;}
struct P{int x;__int128 y;P(){}P(int _x,__int128 _y):x(_x),y(_y){}};
bool cmp(const P elem1,const P elem2){
if(elem1.y==elem2.y)return elem1.x>elem2.x;
return elem1.y<elem2.y;
}
__int128 a[maxn];
__int128 b[maxn];
P sum[maxn];
int Case = 1;
struct node{
__int128 sum;
__int128 lazy;
}tree[maxn<<2];
inline __int128 read(){
__int128 x=0,f=1;
char ch=getchar();
while(ch<'0'||ch>'9'){
if(ch=='-')
f=-1;
ch=getchar();
}
while(ch>='0'&&ch<='9'){
x=x*10+ch-'0';
ch=getchar();
}
return x*f;
} inline void fprint(__int128 x){
if(x<0){
putchar('-');
x=-x;
}
if(x>9)
fprint(x/10);
putchar(x%10+'0');
} void build(int rt,int l,int r){
tree[rt].sum=tree[rt].lazy=0;
if(l==r){
tree[rt].sum = b[l];
return ;
}
int mid = (l+r)>>1;
build(ls,l,mid);
build(rs,mid+1,r);
tree[rt].sum = min(tree[ls].sum,tree[rs].sum);
}
void pushdown(int rt,int l,int r){
if(tree[rt].lazy){
__int128 val = tree[rt].lazy;
tree[ls].sum-=val;
tree[rs].sum-=val;
tree[ls].lazy += val;
tree[rs].lazy += val;
tree[rt].lazy = 0;
}
}
void update(int rt,int l,int r,int L,int R,__int128 val){
if(l>=L&&r<=R){
tree[rt].sum -=val;
tree[rt].lazy += val;
return ;
}
pushdown(rt,l,r);
int mid= (l+r)>>1;
if(L<=mid)update(ls,l,mid,L,R,val);
if(R>mid)update(rs,mid+1,r,L,R,val);
tree[rt].sum = min(tree[ls].sum,tree[rs].sum);
}
__int128 ask(int rt,int l,int r,int L,int R){
if(l>=L&&r<=R){
return tree[rt].sum;
}
pushdown(rt,l,r);
int mid = (l+r)>>1;
__int128 res = inf;
if(L<=mid)res=min(res,ask(ls,l,mid,L,R));
if(R>mid)res=min(res,ask(rs,mid+1,r,L,R));
return res;
}
void solve() {
int n;
scd(n);
sum[0].y = 0;
for(int i=1;i<=n;i++){
a[i]=read();
sum[i].x=i;
sum[i].y=a[i]+sum[i-1].y;
}
for(int i=1;i<=n;i++)b[i]=read();
sort(sum+1,sum+n+1,cmp);
__int128 visit = b[1];
build(1,1,n);
__int128 ans = 0;
for(int i=n;i>=1;i--){
__int128 cnt = ask(1,1,n,1,sum[i].x);
ans+= cnt*sum[i].y;
update(1,1,n,1,sum[i].x,cnt);
}
printf("Case #%d: ",Case);
fprint(visit);
printf(" ");
fprint(ans);
printf("\n"); }
void Main(){
int _;
scd(_);
while(_--)
solve(),++Case; }
//#define _Debug
int main(){
#ifdef _Debug
freopen("data.in","r",stdin);
clock_t b = clock();
Main();
clock_t e = clock();
cout<<"the time of cost is "<<(e-b)<<endl;
#else
Main();
#endif
return 0;
}

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. day13 作业

    目录 1.编写文件修改功能,调用函数时,传入三个参数(修改的文件路径,要修改的内容,修改后的内容)既可完成文件的修改 2.编写tail工具 3.编写登录功能 4.编写注册功能 选做题:编写ATM程序实 ...

  2. python numpy indexerror: too many indices for array

    import numpy as np #data 原来数组 #arr_1 新数组 #将data的第一列赋值给arr_1的第一列 arr_1 = np.array((data.shape[0],5)) ...

  3. 数据库04 /多表查询、pymysql模块

    数据库04 /多表查询.pymysql模块 目录 数据库04 /多表查询.pymysql模块 1. 笛卡尔积 2. 连表查询 2.1 inner join 内连接 2.2 left join 左连接 ...

  4. 数据可视化之powerBI技巧(十九)DAX作图技巧:使用度量值动态分组和配色

    有了前两篇关于分组的铺垫,这篇文章就来学习一个分组的经典应用,图表的动态分组,并对分组动态配色. 假设有十几个产品,每个产品的销售额,是随着时间而变化的,想知道某个时间的每一个产品的销售额与平均销售额 ...

  5. Flask 基础组件(四):模板

    1.模板的使用 1.1  语法 1.1.1 流程控制 逻辑语法 Jinja2模板语言中的 for {% for foo in g %} {% endfor %} Jinja2模板语言中的 if {% ...

  6. redis(二):Redis 命令

    Redis 命令用于在 redis 服务上执行操作. 要在 redis 服务上执行命令需要一个 redis 客户端.Redis 客户端在我们之前下载的的 redis 的安装包中. 语法 Redis 客 ...

  7. java 使用正则去重

    //去重复 public static void test1() { String str = "aaactttsssfvvvvds"; String regex = " ...

  8. 网上一些sql题目的解决(网上答案+自己答案)

    此篇博客内容引自“MySQL经典练习题及答案” 废话不不多说!!! 建表.插入数据. --建表 --学生表 CREATE TABLE Student( s_id VARCHAR(20), s_name ...

  9. tineMCE 踩坑:images_upload_handler

    tineMCE 的官方示例提供了前端上传图片方法 images_upload_handler 的写法. 但官方写的有点问题,上传会报错. 不过修改也很简单: images_upload_handler ...

  10. 题解 UVA501 【Black Box】

    思路与中位数一题,解决方案比较像,使用对顶堆来解决. 具体实现为,使用两个堆,大根堆维护较小的值,小根堆维护较大的值,即小根堆的堆顶是较大的数中最小的,大根堆的堆顶是较小的数中最大的. 将大于大根堆堆 ...