191102CSP模拟DAY2

今天真的是状态一点都不好,希望下次加油吧

T1:极好的问题

传送门

这道题,如果我们暴力枚举每种情况是会炸掉的,所以我们从 x ∗ y ∗ z x*y*z xyz m o d mod mod p p p = = = 1 1 1入手,可以发现,这其实可以转化成逆元的形式,我们设 x ∗ y x*y xy z z z的逆元,再用一个 h a s h hash hash表解决是否出现,就能快速解决,另外要注意, s e t 和 m a p set和map setmap是很慢的,要尽量避免使用,还有可能出现 x ∗ x ∗ y x*x*y xxy m o d mod mod p p p = 1 =1 =1的情况,要单独处理。

代码:

#include<bits/stdc++.h>
#define int long long
#define db double
#define re register
#define cs const
#define N 15000005
#define mod 11114123
using namespace std;
inline int read()
{
	int x=0,f=1;
	char ch;
	while(ch>'9'||ch<'0')
	{
		if(ch=='-')	f=-1;
		ch=getchar();
	}
	while(ch>='0'&&ch<='9')
	{
		x=x*10+ch-'0';
		ch=getchar();
	}
	return f*x;
}
int hashh[N],num[N];
int n,w[10005],ans,last,temp,p;
bool mark[10005];
int loca(int b)
{
	temp=b%mod+1;
	while(hashh[temp]&&hashh[temp]!=b)	++temp;
	return temp;
}
void add(int b)
{
	temp=loca(b);
	if(!hashh[temp])	hashh[temp]=b;
	++num[temp];
}
int ni(int a)
{
	int ans=1;
	int b=p-2;
	while(b)
	{
		if(b&1)	ans=ans*a%p;
		a=a*a%p;
		b/=2;
	}
	return ans;
}
signed main()
{
	n=read();
	p=read();
	for(re int i=1;i<=n;++i)	w[i]=read();
	sort(w+1,w+1+n);
	for(re int i=1;i<=n;++i)
	{
		if(w[i]%p==0)
		{
			mark[i]=1;
			continue;
		}
		int ww=ni(w[i]);
		temp=loca(ww);
		ans+=num[temp];
		if(w[i]==w[i-1])	ans-=last;
		last=num[temp];
		if(w[i]!=w[i-1])
		{
			for(re int j=1;j<i;++j)
			{
				if(mark[j]||w[j]==w[j-1])	continue;
				add(w[i]*w[j]%p);
			}	
		}	
		else if(w[i-1]!=w[i-2])	add(w[i]*w[i]%p);
	}
	printf("%lld",ans);
}

T2:背包问题

传送门

如果没有这个背包的限,其实就是一个二维偏序问题,可是(它有 ),
于是我们可以想到一种贪心来解决背包,即用容量最大的 l l l个背包一定是最优的背包安排,所以我们先按重量降序将物品排序,背包按升序排列,再用 2 2 2 l o w e r lower lower_ b o u n d bound bound,先查找刚好能装此物品的背包,再维护一个单调递减序列即可。

代码:

#include<bits/stdc++.h>
#define ll long long
#define db double
#define re register
#define cs const
#define N 100005
using namespace std;
inline int read()
{
	int x=0,f=1;
	char ch;
	while(ch>'9'||ch<'0')
	{
		if(ch=='-')	f=-1;
		ch=getchar();
	}
	while(ch>='0'&&ch<='9')
	{
		x=x*10+ch-'0';
		ch=getchar();
	}
	return f*x;
}
struct node
{
	int w,v;
}thing[N];
bool cmp(cs node &a,cs node &b)
{
	if(a.w!=b.w)	return a.w>b.w;
	return a.v>b.v;
}
int t,bag[N],n,m,val[N+2000],ans;
int main()
{
	t=read();
	while(t--)
	{
		memset(val,0,sizeof(val));
		n=read();
		for(re int i=1;i<=n;++i)	thing[i].w=read(),thing[i].v=read();
		m=read();
		ans=0;
		for(re int i=1;i<=m;++i)	bag[i]=read();
		sort(bag+1,bag+1+m);
		sort(thing+1,thing+1+n,cmp);
		for(re int i=1;i<=n;++i)
		{
			int lcmm=lower_bound(bag+1,bag+1+m,thing[i].w)-bag;
			int lcnn=lower_bound(val+1,val+N,thing[i].v)-val;
			lcnn=N-lcnn+1;
			lcnn=min(lcnn,m-lcmm+1);
			ans=max(ans,lcnn);
			val[N-lcnn]=max(val[N-lcnn],thing[i].v);
		}
		printf("%d\n",ans);
	}
}

T3:子树问题

传送门

咕咕咕!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值