加载中…

返回上一页

CSP-S加赛0912

下发文件和题解

A. 世界冰球锦标赛

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

题目描述

今年的世界冰球锦标赛在捷克举行。Bobek 已经抵达布拉格,他不是任何团队的粉丝,也没有时间观念。他只是单纯的想去看几场比赛。如果他有足够的钱,他会去看所有的比赛。不幸的是,他的财产十分有限,他决定把所有财产都用来买门票。

给出 Bobek 的预算和每场比赛的票价,试求:如果总票价不超过预算,他有多少种观赛方案。如果存在以其中一种方案观看某场比赛而另一种方案不观看,则认为这两种方案不同。

输入格式

第一行,两个正整数 (1\le N\le40,1\le M\le10^{18}),表示比赛的个数和 Bobek 那家徒四壁的财产。

第二行, 个以空格分隔的正整数,均不超过 ,代表每场比赛门票的价格。

输出格式

输出一行,表示方案的个数。

样例

样例输入

5 1000
100 1500 500 500 1000

样例输出

8

数据范围与提示

有十组数据,每通过一组数据你可以获得 10 分。各组数据的数据范围如下表所示:

数据组号

题目与CSP-S加赛0905的T2一样,折半搜索即可.

点击查看代码
#include<bits/stdc++.h>
#define ll long long
#define rg register
#define rll rg ll
#define maxn 5000001
#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,mid,zzy,ans;
ll a[41];
ll z[maxn],totz,y[maxn],toty;
static inline void dfszuo(rll x,rll mx)
{
	if(mx>m) return;
	if(x>mid) { z[++totz]=mx; return; }
	dfszuo(x+1,mx+a[x]);dfszuo(x+1,mx);
}
static inline void dfsyou(rll x,rll mx)
{
	if(mx>m) return;
	if(x>n) { y[++toty]=mx; return; }
	dfsyou(x+1,mx+a[x]);dfsyou(x+1,mx);
}
int main()
{
	n=read();m=read();
	for(rll i=1;i<=n;i++) a[i]=read();
	sort(a+1,a+n+1);n=upper_bound(a+1,a+n+1,m)-a-1;
	mid=(n>>1);dfszuo(1,0);dfsyou(mid+1,0);
	sort(z+1,z+totz+1);sort(y+1,y+toty+1);
	zzy=upper_bound(y+1,y+toty+1,m)-y-1;
	for(rll i=1;i<=totz;i++)
	{
		while(zzy&&z[i]+y[zzy]>m) zzy--;if(!zzy) break;
		ans+=zzy;
	}
	write(ans);
	return 0;
}

B. 滚

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

用莫队处理出现的次数,根号分治,用一个单调队列(我这里用的set)判断是否合法即可.

点击查看代码
#include<bits/stdc++.h>
#define ll long long
#define rg register
#define rll rg ll
#define maxn 200001
#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,len,l=1,r,mx;
ll a[maxn],b[maxn],w[maxn],ans[maxn],cnt[maxn],num[maxn];
ll sq,st[maxn],ed[maxn],bel[maxn];
set<ll> s;
struct node
{
	ll l,r,k,id;
	inline friend bool operator<(rg node a,rg node b)
	{
		if(bel[a.l]!=bel[b.l]) return bel[a.l]<bel[b.l];
		if(bel[a.l]&1) return a.r>b.r;return a.r<b.r;
	}
}q[maxn];
static inline void upd(rll x,rll op)
{
	if(op==1)
	{
		if(num[x]) { cnt[num[x]]--;if(!cnt[num[x]]) s.erase(s.lower_bound(num[x])); }
		if(!cnt[++num[x]]) s.insert(num[x]);cnt[num[x]]++;
	}
	else
	{
		cnt[num[x]]--;
		if(!cnt[num[x]]) s.erase(s.lower_bound(num[x]));
		num[x]--;if(!num[x]) return;
		if(!cnt[num[x]]) s.insert(num[x]);cnt[num[x]]++;
	}
}
int main()
{
	n=read();m=read();for(rll i=1;i<=n;i++) a[i]=b[i]=read();
	sort(b+1,b+n+1);len=unique(b+1,b+n+1)-b-1;for(rll i=1;i<=n;i++) a[i]=lower_bound(b+1,b+len+1,a[i])-b;
	sq=sqrt(n);for(rll i=1;i<=sq;i++) st[i]=(ll)(n/sq)*(i-1)+1,ed[i]=(ll)(n/sq)*i;ed[sq]=n;for(rll i=1;i<=sq;i++) for(rll j=st[i];j<=ed[i];j++) bel[j]=i;
	for(rll i=1;i<=n;i++) w[i]=read();for(rll i=1;i<=m;i++) q[i]=(node){read(),read(),read(),i};sort(q+1,q+m+1);
	for(rll i=1;i<=m;i++)
	{
		mx=-1;
		while(l>q[i].l) upd(a[--l],1);
		while(r<q[i].r) upd(a[++r],1);
		while(l<q[i].l) upd(a[l++],-1);
		while(r>q[i].r) upd(a[r--],-1);
		for(rg set<ll>::iterator j=++s.begin();j!=s.end();j++) { if((*j)<=(*--j)+q[i].k) mx=max(mx,w[*++j]);else j++; }
		ans[q[i].id]=mx;
	}
	for(rll i=1;i<=m;i++) write(ans[i]),putn;
	return 0;
}
posted @ 2022-09-13 07:35  1Liu  阅读(16)  评论(0)    收藏  举报