• 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
  • 相关阅读:
    线程系列2---线程同步
    off() 方法 与 unbind() 方法移除绑定事件的处理程序。one()函数用于为每个匹配元素的一个或多个事件绑定一次性事件处理函数
    animation css3动画与CSS3 @keyframes担配使用创建往复平缓动画
    querySelector 和 querySelectorAll 的使用
    js实现浏览器兼容复制功能
    evaluateScript--evaluatePopoverScript--区别
    appcan 跨窗口处理方法 appcan.window.evaluateScript({name,scriptContent,type})使用解读
    条件注释判断浏览器<!--[if !IE]><!--[if IE]><!--[if lt IE 6]><!--[if gte IE 6]>
    stop() 是用于停止动画 :animated 用于判断动画是否在进行中
    CSS3的calc()使用
  • 原文地址:https://www.cnblogs.com/yyc-jack-0920/p/9816525.html
Copyright © 2020-2023  润新知