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

代码:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define rii register int i
#define rij register int j 
#define int long long
using namespace std;
int n1,m1,p,nl[100005],t;
int pf[10]={0,1,10,15,25,40,55,75,100};
int pow(int a,int b,int p)
{
    int res=1;
    while(b)
    {
        if(b&1)
        {
            res=res*a%p;
        }
        a=a*a%p;
        b>>=1;
    }
    return res;
}
int exgcd(int a,int b,int& x,int& y)
{
    if(!b)
    {
        x=1;
        y=0;
        return a;
    }
    int res=exgcd(b,a%b,y,x);
    y-=(a/b)*x;
    return res;
}
int reverse(int a,int p)
{
    int x,y;
    exgcd(a,p,x,y);
    return (x%p+p)%p;
}
int C(int n,int m,int p)
{
    if(m>n)
    {
        return 0;
    }
    int res=1,i,a,b;
    for(i=1;i<=m;i++)
    {
        a=(n+1-i)%p;
        b=reverse(i%p,p);
        res=res*a%p*b%p;
    }
    return res;
}
int Lucas(int n,int m,int p)
{
    if(m==0)
    {
        return 1;
    }
    return Lucas(n/p,m/p,p)*C(n%p,m%p,p)%p;
}
int cal(int n,int a,int b,int p)
{
    if(!n)
    {
        return 1;
    } 
    int i,y=n/p,tmp=1;
    for(i=1;i<=p;i++)
    {
        if(i%a)
        {
            tmp=tmp*i%p;
        }
    }
    int ans=pow(tmp,y,p);
    for(i=y*p+1;i<=n;i++)
    {
        if(i%a)
        {
            ans=ans*i%p;
        } 
        
    } 
    return ans*cal(n/a,a,b,p)%p;
}
int multiLucas(int n,int m,int a,int b,int p)
{
    int i,t1,t2,t3,s=0,tmp;
    for(i=n;i;i/=a)
    {
        s+=i/a;
    }
    for(i=m;i;i/=a)
    {
        s-=i/a;
    }
    for(i=n-m;i;i/=a)
    {
        s-=i/a;
    }
    tmp=pow(a,s,p);
    t1=cal(n,a,b,p);
    t2=cal(m,a,b,p);
    t3=cal(n-m,a,b,p);
    return tmp*t1%p*reverse(t2,p)%p*reverse(t3,p)%p;
}
int exLucas(int n,int m,int p)
{
    int i,d,c,t,x,y,q[100],a[100],e=0;
    for(i=2;i*i<=p;i++)
    {
        if(p%i==0)
        {
            q[++e]=1;
            t=0;
            while(p%i==0)
            {
                p/=i;
                q[e]*=i;
                t++;
            }
            if(q[e]==i)
            {
                a[e]=Lucas(n,m,q[e]);
            }
            else
            {
                a[e]=multiLucas(n,m,i,t,q[e]);
            }
        }
    }
    if(p>1)
    {
        e++;
        q[e]=p;
        a[e]=Lucas(n,m,p);
    }
    for(i=2;i<=e;i++)
    {
        d=exgcd(q[1],q[i],x,y);
        c=a[i]-a[1];
        if(c%d)
        {
            exit(-1);
        }
        t=q[i]/d;
        x=(c/d*x%t+t)%t;
        a[1]=q[1]*x+a[1];
        q[1]=q[1]*q[i]/d;
    }
    return a[1];
}
inline int rd(){
    int x=0,f=1;char ch=getchar();
    while(!isdigit(ch)) {f=ch=='-'?0:1;ch=getchar();}
    while(isdigit(ch))  {x=(x<<1)+(x<<3)+ch-'0';ch=getchar();}
    return f?x:-x;
}
bool cmp(int lk,int kl)
{
    return lk<kl;
}
void solve()
{
    n1=rd();
    m1=rd();
    p=rd();
//    scanf("%lld%lld%lld",&n,&m,&p);
    for(rii=1;i<=n1;i++)
    {
        nl[i]=rd();
//        scanf("%lld",&nl[i]);
    }
    sort(nl+1,nl+n1+1,cmp);
    int minx=10,jsq=0;
    for(rii=1;i<=m1;i++)
    {
        int val;
        val=rd();
//        scanf("%lld",&val);
        minx=min(minx,val);
        jsq+=pf[val];
    }
    jsq-=pf[minx];
    int cha=(m1-1)*71-jsq;
    int mins=cha/29;
    if(mins*29<cha)
    {
        mins++;
    }
    if(cha<=0)
    {
        mins=0;
    }
    int ans=0;
    int zx;
    zx=rd();
//    scanf("%lld",&zx);
    int cnt=n1;
    for(rii=1;i<=n1;i++)
    {
        if(nl[i]<zx)
        {
            cnt--;
        }
        else
        {
            break;
        }
    }
    n1=cnt;
    for(rii=mins+1;i<=n1;i++)
    {
        ans+=exLucas(n1,i,p);
        ans%=p;
    }
    printf("%lld\n",ans);
}
signed main()
{
//     freopen("pf10.in","r",stdin);
//     freopen("pf10.out","w",stdout);
    scanf("%lld",&t);
    for(rii=1;i<=t;i++)
    {
        solve();
    }
}

猜你喜欢

转载自www.cnblogs.com/ztz11/p/9900246.html