191108-模拟测试14
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=a∗pi−1+b∗pi+c∗pi+1 第一眼看上去,觉得是高斯消元,但在仔细看了数据范围过后,高斯消元直接否掉,那么我们再来观察这个式子,其实这个式子非常特殊,因为我们已知p0和p2np_0和p_{2n}p0和p2n 因此我们可以把p2...p2∗np_{2}...p_{2*n}p2...p2∗n都用p1p_1p1表示出来,再用p2np_{2n}p2n将p1p_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
题目描述
解析
先去学了莫队再说吧