NOIp膜你题 Day2
duliu 出题人:ZAY
题解
这就是一道组合数问题鸭!!! 可是泥为什么没有推出式子!!
首先我们知道的是 m 盆花都要摆上,然后他们的顺序不定(主人公忘记了)
所以初步得到一个排列数 P( m,m ) , 即 Pmm
那么我们就还剩下 n-m 个空位置,这些空位置都是不可以放花的,于是我们逆向思维一下:
n-m 个位置不放花,也就是可以在这些位置周围插空放花,把这些位置隔开,那么就可以把m盆花放到 n-m+1 个空里,由于这是对于空位置来说的,没有顺序可言,每个都是一毛一样的,所以得到一个组合数 C(n-m+1 , m) , 即 Cn-m+1m
所以 ans = P( m,m ) * C( n-m+1 , m )
= m! * (n-m+1)! / [ m! * (n-m+1 - m)! ]
化简一下就是下面
=(n-m+1)*(n-m+1-1)*......*(n-2m+2)
注意
ans 要开 long long , 试过毒了,数据不开 long long 会炸
代码
#include<bits/stdc++.h> using namespace std; int type,n,m,p; long long ans=1; int main() { freopen("ilove.in","r",stdin); freopen("ilove.out","w",stdout); scanf("%d%d%d%d",&type,&n,&m,&p); if(n==1&&m==1) { printf("1\n"); return 0; } int a=n-m+1,b=n-m-m+2; for(int i=a;i>=b;i--) ans=(ans%p*i%p)%p; printf("%ld\n",ans); return 0; }
题解
代码
45‘代码 后边超时辣
#include<bits/stdc++.h> #include<iostream> #include<cstdio> #include<cstring> #include<string> #include<algorithm> #include<cmath> using namespace std; string s[100009],s1; int n,m,q; int qus,num,l,r; long long ans=0; int main() { freopen("lin.in","r",stdin); freopen("lin.out","w",stdout); scanf("%d%d%d",&n,&m,&q); if(q==0) return 0; for(int i=1;i<=m;i++) cin>>s[i]; for(int i=1;i<=q;i++) { ans=0; scanf("%d",&qus); if(qus==0) { scanf("%d%d",&l,&r); int flag=520,cnt=0; for(int j=0;j<n;j++) { if(flag==0) break; bool glf=0; char mp; mp=s[l][j]; if(mp!='?') glf=0; else glf=1; for(int k=l+1;k<=r;k++) { if(s[k][j]!='?') { if(mp=='?') { glf=1; mp=s[k][j]; continue; } if(mp!='?'&&mp!=s[k][j]) { flag=0; continue; } } else if(s[k][j]=='?') { if(glf==0) glf=1; } } if(mp!='?') glf=0; cnt+=glf; } if(flag==0) {printf("0\n");} else { ans=pow(2,cnt); printf("%ld\n",ans); } } if(qus==1) { scanf("%d",&num); cin>>s1; s[num]=s1; } } return 0; }
thingKing 但是下面这个它还没过样例
#include<bits/stdc++.h> using namespace std; int n,m,q; string s[100010],s1; int opt,l,r,pos; inline int read() { int ans=0; char last=' ',ch=getchar(); while(ch<'0'||ch>'9') last=ch,ch=getchar(); while(ch>='0'&&ch<='9') ans=ans*10+ch-'0',ch=getchar(); if(last=='-') ans=-ans; return ans; } int main() { // freopen("lin.in","r",stdin); // freopen("lin.out","w",stdout); n=read(); m=read(); q=read(); for(int i=1;i<=m;i++) cin>>s[i]; /* cout<<"\n"; for(int i=1;i<=m;i++) cout<<s[i] <<"\n"; */ cout<<"\n"; for(int i=1;i<=q;i++) { opt=read(); if(opt==1) { pos=read(); cin>>s1; s[pos]=s1; } else { l=read();r=read(); long long ans; int flag=1,cnt=0; for(int j=0;j<n;j++) { if(flag==0) break; int flag0=0,flag1=0,flag2=0; for(int k=l;k<=r;k++) { if(s[k][j]=='0') flag0++; if(s[k][j]=='1') flag1++; if(s[k][j]=='?') flag2++; } if(flag0!=0&&flag1!=0) { flag=0; continue; } else if(flag2==(r-l+2)) cnt++; } if(flag==0) ans=0; else ans=pow(2,cnt); // printf("%d %d ",flag,cnt); printf("%ld\n",ans); } } return 0; }