ztz11的noip模拟赛T3:评分系统

时间:2022-10-10 23:37:36

(本题markdown好像挂了,请移步另一篇我重写的https://www.cnblogs.com/ztz11/p/9900246.html)

比较良心的部分分(50pts)
前30分可以暴力
另20分可以递推
对于这道题,化简下来,就是\(C_n^{minx+1}+C_n^{minx+2}+...+C_n^n\)
(n为合格的水军数量,minx为最少需要的水军数量(因为要去掉最高分,所以我们要+1))
然后对于p=质数的情况,lucas定理即可
p!=质数的话用exlucas就行
当然,据说有人暴力能水不少分?tql!(可能是我数据出水了)

代码:

include

include

include

define rii register int i

define rij register int j

define int long long

using namespace std;
int nl[100005],n,m,k,pf[15]={0,1,10,15,25,40,55,75,100};
int t,ny[100005];
void qny(int p1)
{
ny[1]=1;
for(rii=2;i<=100000;i++)
{
ny[i]=(p1-p1/i)ny[p1%i];
}
}
int zhsx(int n1,int m1,int p1)
{
long long ans=1;
for(rii=1;i<=m1;i++)
{
ans
=ny[i];
ans%=p1;
}
for(rii=n1;i>=n1-m1+1;i--)
{
ans=i;
ans%=p1;
}
return ans;
}
void solve()
{
int p;
int minx=2147483647;
int jsq=0;
scanf("%lld%lld%lld",&n,&m,&p);
qny(p);
for(rii=1;i<=n;i++)
{
scanf("%lld",&nl[i]);
}
for(rii=1;i<=m;i++)
{
int val;
scanf("%lld",&val);
minx=min(minx,val);
jsq+=pf[val];
}
jsq-=pf[minx];
int cha=(m-1)
71-jsq;
int mins=cha/29;
if(mins*29<cha)
{
mins++;
}
if(cha<=0)
{
mins=0;
}
int ans=0;
int zx;
scanf("%lld",&zx);
int cnt=n;
for(rii=1;i<=n;i++)
{
if(nl[i]<zx)
{
cnt--;
}
else
{
break;
}
}
n=cnt;
for(rii=mins+1;i<=n;i++)
{
ans+=zhsx(n,i,p);
ans%=p;
}
printf("%lld\n",ans);
}
signed main()
{
scanf("%lld",&t);
for(rii=1;i<=t;i++)
{
solve();
}
}