191108-模拟测试14

本文精选了三道算法竞赛题目,包括药品试验、小猫钓鱼和模式匹配问题,详细解析了每道题目的核心思想与高效算法实现,如逆元求解、模拟策略和莫队算法,对于算法学习者具有较高的参考价值。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

191108-模拟测试14

T1 药品试验

题目描述

T1

解析

首先讲讲考场思想,因为所给的a,b都是取模意义下的,所以几乎前一半的时间都在考虑如何通过已知的有理数逆元,来求有理数,显然我是个沙雕 ,其实完全可以不用求出那个有理数,只需要用逆元来求就好了,因为最后所求的也是逆元,因此还是用逆元求就好了,

但是仅仅知道这个,也无法解决该题,因为该题还有个式子为pi=a∗pi−1+b∗pi+c∗pi+1p_i=a*p_{i-1}+b*p_i+c*p_{i+1}pi=api1+bpi+cpi+1 第一眼看上去,觉得是高斯消元,但在仔细看了数据范围过后,高斯消元直接否掉,那么我们再来观察这个式子,其实这个式子非常特殊,因为我们已知p0和p2np_0和p_{2n}p0p2n 因此我们可以把p2...p2∗np_{2}...p_{2*n}p2...p2n都用p1p_1p1表示出来,再用p2np_{2n}p2np1p_1p1求出来,从而求得pnp_npn,当然这样时间复杂度为O(n)O(n)O(n),会被卡

因此我们来考虑O(1)O(1)O(1)的做法,首先给出通项公式pn=cncn+anp_n=\frac{c^n}{c^n+a^n}pn=cn+ancn,至于怎么推的嘛,先咕掉

题解

#include<bits/stdc++.h>
#define int long long
using namespace std;
int d,mod=1e9+7;
int ksm(int a,int b){
	int ans=1;
	while(b){
		if(b&1) ans=(ans*a)%mod;
		a=a*a%mod;
		b>>=1;
	}
	return ans;
}
signed main(){
	//freopen("experiment.in","r",stdin);
	//freopen("experiment.out","w",stdout);
	int n,a,b,x,y,ans;
	scanf("%lld%lld%lld",&n,&a,&b);
	x=(mod+1-a)*b%mod;
	y=a*(mod+1-b)%mod;
	int p=ksm(y,n)%mod;
	int q=(ksm(x,n)%mod+p)%mod;
	q=ksm(q,mod-2);
	ans=p*q%mod;
	printf("%lld",ans);
	return 0;
}

T2 小猫钓鱼

题目描述

在这里插入图片描述

解析

模拟,注意一下细节,卡波常就好了

题解

#include<bits/stdc++.h>
#define re register
using namespace std;
int a[109][100009],c[10009],tail[109],head[109],cnt,cur,len,ans[109],bj[10009],vis[109],n,num,m,l,s,t,top,b[10000009],val[10009],insta[10009],d[10009];
inline int read(){
	int f=1,re1=0;
	char ch;
	for(ch=getchar();!isdigit(ch)&&ch!='-';ch=getchar());
	if(ch=='-'){
		f=-1;
		ch=getchar();
	}
	for(;isdigit(ch);ch=getchar()){
		re1=(re1<<3)+(re1<<1)+ch-'0';
	}
	return re1*f;
}
inline void print(int x)//输出优化
{
    if(x<0){
        putchar('-');
        x=-x;
    }
    if(x>9)
        print(x/10);
    putchar(x%10+'0');
}
inline void clear(){
	for(re int i=1;i<=n;i++)
		vis[i]=ans[i]=0;
	memset(insta,0,sizeof(insta));
	memset(val,0,sizeof(val));
	cnt=0;
	top=0;
	num=0;
}
signed main(){
	//freopen("fishing.in","r",stdin);
	//freopen("fishing.out","w",stdout);
	cnt=0;
	while(1){
		n=read();
		m=read();
		l=read();
		s=read();
		t=read();
		if(n==-1) break;
		clear();
		for(re int i=1;i<=n;i++)
			for(re int j=1;j<=l;j++){
				a[i][j]=read();
				c[++cnt]=a[i][j];
				tail[i]=l;
				head[i]=1;
			}
		c[++cnt]=s;
		sort(c+1,c+cnt+1);
		len=unique(c+1,c+cnt+1)-c-1;
		for(re int i=1;i<=n;i++)
			for(re int j=1;j<=l;j++){
				int pos=lower_bound(c+1,c+len+1,a[i][j])-c;
				val[pos]=a[i][j];
			}
		s=lower_bound(c+1,c+len+1,s)-c;
		bj[s]=1;//s可能不在原序列中 
		for(re int i=1;i<=t;i++){
			if(num==n-1||num==n) 
				break;
			for(re int j=1;j<=n;j++){
				if(vis[j]) continue;
				int pos=lower_bound(c+1,c+len+1,a[j][head[j]])-c;
				head[j]++;
				if(bj[pos]){
					if(!top) b[++top]=pos;
					else{
						for(int k=1;k<=top;k++){
							insta[b[k]]=0;
							a[j][++tail[j]]=val[b[k]];
						}
						a[j][++tail[j]]=val[pos];
						top=0;
					} 
				}
				else{
					if(insta[pos]){
						cur=0;
						while(b[top]!=pos){
							d[++cur]=val[b[top]];
							insta[b[top]]=0;
							top--;
						}
						d[++cur]=val[pos];
						insta[pos]=0;
						top--;
						for(int k=cur;k>=1;k--){
							a[j][++tail[j]]=d[k];
						}
						a[j][++tail[j]]=val[pos];
					}
					else{
						b[++top]=pos;
						insta[pos]=1;
					}
				}
				if(head[j]>tail[j]) vis[j]=1,ans[j]=-i,num++;
			}
		}
		for(re int i=1;i<=n;i++){
			if(vis[i]) print(ans[i]);
			else print(tail[i]-head[i]+1);
			printf(" ");
		}
		printf("\n");
		for(re int i=1;i<=n;i++){
			if(!vis[i])
				for(re int j=head[i];j<=tail[i];j++)
				{
					print(a[i][j]);
					printf(" ");
				}
			printf("\n");
		}
		bj[s]=0;
 	}
	return 0;
}

T3 mode

题目描述

解析

先去学了莫队再说吧

题解

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值