加载中…

返回上一页

CSP-S加赛0916

下发文件和题解

T1 乌鸦喝水



内存限制:128 MiB 时间限制:2000 ms 标准输入输出
题目类型:传统 评测方式:文本比较

题目描述

一只乌鸦在自娱自乐,它在面前放了n个有魔力的水缸,水缸里装有无限的水.

他准备从第1个水缸飞到第n个水缸,共m次. 在飞过一个水缸的过程中,如果他能够得着水缸里的水,即水缸口到水面距离小于等于乌鸦能够得着的深度,那它就会喝水缸里的水. 每喝一次水,所有水缸里的水位都会下降,第i个水缸里的水位会下降Ai,注意喝水是瞬间的,如果乌鸦刚好够得着,但喝完之后够不着,也视为喝到一次,水位也会相应的下降.

输入格式

共有3行. 第一行有三个正整数n、m和x,用空格隔开. n表示水缸的数量,m表示乌鸦飞的次数,x表示乌鸦能够得着的深度.
第二行,有n个用空格隔开的正整数,第i个数为第i个水缸中水缸口到水面的距离Wi.
第三行,有n个用空格隔开的正整数,第i个为Ai.

输出格式

只有一行,这一行只有一个正整数,为这只乌鸦能喝到水的次数.

样例

样例输入

5 2 20
15 14 13 12 12
1 1 1 1 1

样例输出

9

数据范围与提示

100%的数据,0<n≤100000,0<m≤100000,0<x≤2000000000,0<Wi≤2000000000,0<Ai≤200.

感谢巨佬的悉心指导

首先没有人会不去把深度换成次数. 注意是水缸口到水面距离小于{等于}乌鸦能够得着的深度. 因为这个我调了120分钟.

发现乌鸦在前面有水时一定会先喝前面的水,所以这玩意是单调的. 一口剩余次数少的缸必定要先比剩余次数多的缸剩余次数先达到0. 所以把这些缸按照剩余次数从小到大排序,没有剩余次数的删去即可.

枚举每一口缸,把轮数一直增加直到它没水了. 二分这个最后一个让它没水的缸,作为下一口缸枚举的起始点. 在最后的时候,更新答案到这一口缸的剩余次数. 注意轮数超了直接跳出即可.

调试语句就不删了,见证我把每一个部分都调了一遍 精疲力竭了x_x
#include<bits/stdc++.h>
#define ll long long
#define rg register
#define rll rg ll
#define ld double
#define maxn 100001
#define mod 1000000007
#define put_ putchar(' ')
#define putn putchar('\n')
using namespace std;
static inline ll read()
{
	rll f=0,x=0;rg char ch=getchar();
	while(ch<'0'||ch>'9') f|=(ch=='-'),ch=getchar();
	while(ch>='0'&&ch<='9') x=((x<<3))+((x<<1))+(ch^'0'),ch=getchar();
	return f?-x:x;
}
static inline void write(rll x)
{
	if(x<0) putchar('-'),x=-x;
	if(x>9) write(x/10);putchar(x%10|'0');
}

template<typename T,size_t siz>
class bit
{
#define lowbit(x) (x&-x)
private:
	T c[siz];
public:
	inline void upd(rg T x,rg T n,rg T v) { for(rg T i=x;i<=n;i+=lowbit(i)) c[i]+=v; }
	inline T query(rg T x) { rg T ans=0;for(rg T i=x;i;i-=lowbit(i)) ans+=c[i];return ans; }
#undef lowbit
};

struct node
{
	ll a,id;
	inline friend bool operator<(rg node a,rg node b) { return a.a<b.a; }
}b[maxn];
ll n,m,x,st,st1,lun=1,tot,ans;
bit<ll,maxn> t;
static inline bool chk(rll x,rll i) { return t.query(x)-t.query(st)<=b[i].a-ans; }
int main()
{
	n=read();m=read();x=read();
	for(rll i=1;i<=n;i++) b[i].a=x-read();for(rll i=1;i<=n;i++) b[i].a=b[i].a/read()+1;
	for(rll i=1;i<=n;i++) if(b[i].a&&!(b[i].a&LLONG_MIN)) b[++tot].a=b[i].a,b[tot].id=tot;
	n=tot;sort(b+1,b+n+1);for(rll i=1;i<=n;i++) t.upd(i,n,1);// ,write(b[i].a),put_;putn;
	for(rll i=1;i<=n;i++)
	{
		if(b[i].a-ans<0) { t.upd(b[i].id,n,-1); continue; }
		while(lun<=m&&b[i].a-ans>=t.query(n)-t.query(st)) lun++,ans+=t.query(n)-t.query(st),st=0;// ,write(lun),put_;
		// write(i);put_;write(lun);putn;
		if(lun>m) break;
		rll l=st,r=n,mid;while(l<=r) mid=(l+r)>>1,(chk(mid,i)?(st1=mid,l=mid+1):r=mid-1);// ,write(l),put_,write(r),putn;
		ans=b[i].a;st=st1;/*putn;write(b[i].id);put_;write(n);putn;*/t.upd(b[i].id,n,-1);
	}
	write(ans);
	return 0;
}

T2 kill



内存限制:256 MiB 时间限制:1000 ms 标准输入输出
题目类型:传统 评测方式:文本比较



暴力贪心,可以发现最优情况一定是选择一个连续段. 这里我困惑了半天,其实可以模拟一下 s 点在左、中、右三种情况,发现选连续段一定是最优的. 所以枚举 nm 即可. 复杂度 O(nm).

点击查看代码
#include<bits/stdc++.h>
#define ll long long
#define rg register
#define rll rg ll
#define maxn 100001
#define put_ putchar(' ')
#define putn putchar('\n')
using namespace std;
static inline ll read()
{
	rll f=0,x=0;rg char ch=getchar();
	while(ch<'0'||ch>'9') f|=(ch=='-'),ch=getchar();
	while(ch>='0'&&ch<='9') x=((x<<3))+((x<<1))+(ch^'0'),ch=getchar();
	return f?-x:x;
}
static inline void write(rll x)
{
	if(x<0) putchar('-'),x=-x;
	if(x>9) write(x/10);putchar(x%10|'0');
}
ll n,m,s,p[maxn],q[maxn],ans=LLONG_MAX;
int main()
{
	n=read();m=read();s=read();
	for(rll i=1;i<=n;i++) p[i]=read(); for(rll i=1;i<=m;i++) q[i]=read();
	sort(q+1,q+m+1);sort(p+1,p+n+1);
	for(rll j=1;j<=m-n+1;j++)
	{
		rll k=0;
		for(rll i=1;i<=n;i++)
			k=max(k,abs(p[i]-q[j+i-1])+abs(q[j+i-1]-s));
		ans=min(ans,k);
	}
	write(ans);
	return 0;
}
posted @   1Liu  阅读(20)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现

此页面中的资源仅供学习交流使用,请勿转载或外传. 点击“同意”即表示您同意上述内容.

!

Not valid!

点击右上角即可分享
微信分享提示