• 10.19的一些题


    T1 bzoj 1951 古代猪文

    题目大意:

    给正整数n G 求(G^sigma{C(n,n/i),i|n})%P

    思路:

    数论题大合集.jpg

    设res=sigma{C(n,n/i),i|n 由于res可能很大

    由费马小定理可得 我们只需要求res%(P-1)

    快速求C需要lucas 因为P-1不是质数 所以还需要使用中国剩余定理合并

    最后再快速幂即可

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstring>
     4 #include<cstdlib>
     5 #include<cmath>
     6 #include<algorithm>
     7 #include<queue>
     8 #include<vector>
     9 #include<map>
    10 #define inf 2139062143
    11 #define ll long long
    12 #define MAXN 40100
    13 #define MOD 999911659
    14 using namespace std;
    15 inline int read()
    16 {
    17     int x=0,f=1;char ch=getchar();
    18     while(!isdigit(ch)) {if(ch=='-')f=-1;ch=getchar();}
    19     while(isdigit(ch)) {x=x*10+ch-'0';ch=getchar();}
    20     return x*f;
    21 }
    22 int n,inv[4][MAXN],m[4]={2,3,4679,35617};
    23 ll g[4][MAXN],bas,ans[4];
    24 inline void mem()
    25 {
    26     for(int k=0;k<4;k++)
    27     {
    28         inv[k][0]=inv[k][1]=g[k][0]=g[k][1]=1;
    29         for(int i=2;i<m[k];i++) inv[k][i]=(m[k]-m[k]/i)*inv[k][m[k]%i]%m[k],g[k][i]=(g[k][i-1]*i)%m[k];
    30         for(int i=2;i<m[k];i++) (inv[k][i]*=inv[k][i-1])%=m[k];
    31         //cout<<k<<" "<<ans[0]<<" "<<ans[1]<<" "<<ans[2]<<" "<<ans[3]<<endl;
    32         //cout<<inv[k][2]<<endl;
    33     }
    34     //cout<<ans[0]<<" "<<ans[1]<<" "<<ans[2]<<" "<<ans[3]<<endl;
    35 }
    36 inline ll C(ll n,ll x,int k)
    37 {
    38     //cout<<"C: "<<n<<" "<<x<<" "<<k<<" "<<g[k][n]<<" "<<inv[k][x]<<" "<<inv[k][n-x]<<endl;
    39     if(n<x) return 0LL;
    40     return (g[k][n]*inv[k][x]*inv[k][n-x])%m[k];
    41 }
    42 ll lucas(ll n,ll x,int k)
    43 {
    44     //cout<<"L: "<<n<<" "<<x<<" "<<k<<" "<<g[k][n]<<" "<<inv[k][x]<<" "<<inv[k][n-x]<<endl;
    45     if(!x) return 1LL;
    46     return (lucas(n/m[k],x/m[k],k)*C(n%m[k],x%m[k],k))%m[k];
    47     //return *C(n%m[x],x%m[x],k))%m[x];
    48 }
    49 inline void work(int x)
    50 {
    51     for(int i=0;i<4;i++){
    52         //cout<<x<<" "<<i<<" "<<ans[0]<<" "<<ans[1]<<" "<<ans[2]<<" "<<ans[3]<<endl;
    53         (ans[i]+=lucas(n,x,i))%=m[i];
    54     }
    55         //cout<<x<<" "<<ans[0]<<" "<<ans[1]<<" "<<ans[2]<<" "<<ans[3]<<endl;
    56 }
    57 inline ll exgcd(ll a,ll b,ll &x,ll &y)
    58 {
    59     if(!b) {x=1,y=0;return a;}
    60     ll d=exgcd(b,a%b,y,x);y-=(a/b)*x;return d;
    61 }
    62 inline ll q_pow(ll t)
    63 {
    64     //cout<<t<<endl;
    65     ll res=1;
    66     for(;t;t>>=1,(bas*=bas)%=MOD)
    67     {
    68         //cout<<t<<" "<<res<<" "<<bas<<endl;
    69         if(t&1) (res*=bas)%=MOD;
    70     }
    71     return (res+MOD)%MOD;
    72 }
    73 int main()
    74 {
    75     n=read(),bas=read();mem();
    76     if(bas==MOD) {puts("0");return 0;}
    77     for(int i=1;i*i<=n;i++)
    78         if(n%i==0) {work(i);if(i*i!=n) work(n/i);}
    79     ll x,y,s=MOD-1,res=0;
    80     for(int i=0;i<4;i++)
    81     {
    82         exgcd(m[i],s/m[i],x,y);
    83         (res+=y*s/m[i]*ans[i])%=s;
    84         //cout<<y*s/m[i]*ans[i]<<endl;
    85     }
    86     printf("%lld",q_pow((res+s)%s));
    87 }
    View Code

    T2 bzoj 3398 牡牛和牝牛

    题目大意:

    N只牛 这些牛公母任意 牛们要站成一排,任意两头公牛之间至少有k头母牛 

    求有多少种排队方案(所有公牛可看做一样 母牛可看做一样)

    思路:

    dp i 表示前i头的方案 注意dp 1 =2(公母都可以取)

    当这一头为母牛时 dp i+=dp i-1

    为公牛时 dp i += dp i-k-1 当i<=k+1时 dp i++

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstring>
     4 #include<cstdlib>
     5 #include<cmath>
     6 #include<algorithm>
     7 #include<queue>
     8 #include<vector>
     9 #include<map>
    10 #define inf 2139062143
    11 #define ll long long
    12 #define MAXN 100100
    13 #define MOD 5000011
    14 using namespace std;
    15 inline int read()
    16 {
    17     int x=0,f=1;char ch=getchar();
    18     while(!isdigit(ch)) {if(ch=='-')f=-1;ch=getchar();}
    19     while(isdigit(ch)) {x=x*10+ch-'0';ch=getchar();}
    20     return x*f;
    21 }
    22 int n,dp[MAXN],k;
    23 int main()
    24 {
    25     n=read(),k=read(),dp[1]=2;
    26     for(int i=2;i<=n;i++)
    27         if(i<=k+1) dp[i]=dp[i-1]+1;
    28         else (dp[i]=dp[i-1]+dp[i-k-1])%=MOD;
    29     printf("%d
    ",dp[n]);
    30 }
    View Code

    T3 luogu 1771 方程的解

    题目大意:

    正整数 k x 求不定方程a1+a2+...+ak=g(x) g(x)=x^x(mod 1000)的正整数解组数

    思路:

    先快速幂求出g(x) 然后相当于插板 g(x)-1个位置插k-1个板 高精度组合数即可

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstring>
     4 #include<cstdlib>
     5 #include<cmath>
     6 #include<algorithm>
     7 #include<queue>
     8 #include<vector>
     9 #include<map>
    10 #define inf 2139062143
    11 #define ll long long
    12 #define MAXN 100100
    13 using namespace std;
    14 inline int read()
    15 {
    16     int x=0,f=1;char ch=getchar();
    17     while(!isdigit(ch)) {if(ch=='-')f=-1;ch=getchar();}
    18     while(isdigit(ch)) {x=x*10+ch-'0';ch=getchar();}
    19     return x*f;
    20 }
    21 int n,m,MOD=1000;
    22 int q_pow(int t,int p)
    23 {
    24     int res=1;
    25     for(;p;p>>=1,(t*=t)%=MOD)
    26         if(p&1) (res*=t)%=MOD;
    27     return res;
    28 }
    29 struct bign 
    30 {
    31     int num[30],len;
    32     bign(){memset(num,0,sizeof(num));len=0;}
    33     void print()
    34     {
    35         printf("%d",num[len]);
    36         for(int i=len-1;i>=0;i--) printf("%09d",num[i]);
    37     }
    38     bign operator + (const bign a) const
    39     {
    40         bign res;res.len=max(len,a.len);
    41         for(int i=0;i<=res.len;i++)
    42             res.num[i]+=num[i]+a.num[i],
    43             res.num[i+1]=res.num[i]/MOD,res.num[i]%=MOD;
    44         if(res.num[res.len+1]) res.len++;
    45         return res;
    46     }
    47 }c[1010][1010];
    48 int main()
    49 {
    50     n=read()-1,m=read(),m=q_pow(m%MOD,m)-1,MOD=1e9;
    51     c[0][0].num[0]=1;
    52     for(int i=1;i<=m;i++)
    53     {
    54         c[i][0].num[0]=1;
    55         for(int j=1;j<=n&&j<=i;j++) c[i][j]=c[i-1][j]+c[i-1][j-1];
    56     }
    57     c[m][n].print();
    58 }
    View Code

    T4 loj 10232 车的放置

    题目大意:

    形如这样的棋盘 求放k个互不攻击的车(jv) 的方案数

    思路:

    太菜了不会组合数 选择dp i j 表示前i行放了j个棋子的方案数

    可以从i-1 行放了j 个棋子 与 前i-1行放了j-1个转移 后者需要乘这次的方案数

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstring>
     4 #include<cstdlib>
     5 #include<cmath>
     6 #include<algorithm>
     7 #include<queue>
     8 #include<vector>
     9 #include<map>
    10 #define inf 2139062143
    11 #define ll long long
    12 #define MAXN 5010
    13 #define MOD 100003
    14 using namespace std;
    15 inline int read()
    16 {
    17     int x=0,f=1;char ch=getchar();
    18     while(!isdigit(ch)) {if(ch=='-')f=-1;ch=getchar();}
    19     while(isdigit(ch)) {x=x*10+ch-'0';ch=getchar();}
    20     return x*f;
    21 }
    22 int a,b,c,d,k,f[MAXN][MAXN],v[MAXN];
    23 int main()
    24 {
    25     a=read(),b=read(),c=read(),d=read(),k=read();
    26     for(int i=0;i<=b+d;i++) f[i][0]=1;
    27     for(int i=1;i<=b+d;i++)
    28         for(int j=1;j<=k&&j<=i;j++)
    29             if(i<=b) f[i][j]=(f[i-1][j]+f[i-1][j-1]*(a-j+1))%MOD;
    30             else f[i][j]=(f[i-1][j]+f[i-1][j-1]*(a+c-j+1))%MOD;
    31     printf("%d",f[b+d][k]);
    32 }
    View Code

    T5 bzoj 3505 数三角形

    题目大意:

    给定一个nxm的网格,请计算三点都在格点上的三角形共有多少个(三点不共线)

    思路:

    先算出选三个点的方案数再减去共线的方案数

    枚举每个三点共线构成线段的这个向量

    对于每个向量的方案为可以平移到的位置即(n-i)*(m-j)再乘线段上选点的方案数即gcd(i,j)-1

    因为i j为正整数即假设这个线段一端为网格左下角 而左上角的方案相同因此每个向量方案再乘二

    但i j 其中一个等于0时不需要乘2因为平移时已经算过了

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstring>
     4 #include<cstdlib>
     5 #include<cmath>
     6 #include<algorithm>
     7 #include<queue>
     8 #include<vector>
     9 #include<map>
    10 #define inf 2139062143
    11 #define ll long long
    12 #define MAXN 5010
    13 #define MOD 100003
    14 using namespace std;
    15 inline int read()
    16 {
    17     int x=0,f=1;char ch=getchar();
    18     while(!isdigit(ch)) {if(ch=='-')f=-1;ch=getchar();}
    19     while(isdigit(ch)) {x=x*10+ch-'0';ch=getchar();}
    20     return x*f;
    21 }
    22 ll n,m,ans;
    23 int gcd(int a,int b) {if(!a) return b;return !b?a:gcd(b,a%b);}
    24 int main()
    25 {
    26     n=read()+1,m=read()+1,ans=n*m*(n*m-1)*(n*m-2)/6;
    27     for(ll i=0;i<=n;i++)
    28         for(ll j=0;j<=m;j++)
    29             if(i+j) ans-= ((i*j)?2LL:1LL)*(gcd(i,j)-1LL)*(n-i)*(m-j);
    30     printf("%lld",ans);
    31 }
    View Code
  • 相关阅读:
    MySql-数据库基础
    Window安装MySQL
    Python程序中的进程操作-进程间通信(multiprocess.Queue)
    线程
    上传电影代码
    并发编程基础
    基于socketserver实现并发的socket编程
    模拟ssh远程执行命令
    GIT的使用,Pycharm中使用GitHub
    主机如何访问运行在虚拟机中的Django项目
  • 原文地址:https://www.cnblogs.com/yyc-jack-0920/p/9816525.html
Copyright © 2020-2023  润新知