• 快速乘法-快速幂


    Description
    从 n 个不同元素中任取 m(m≤n)个元素,按照一定的顺序排列起来,叫做从 n
    个不同元素中取出 m 个元素的一个排列。当 m=n 时所有的排列情况叫全排列。
    你觉得 xxy 会问你全排列的个数吗?Xxy:这个问题能淹死你,我才不问呢。我
    要问的是求 n 的全排列中,先递增后递
    减、先递减后递增的全排列的个数。由于答案可能很大,对 p 取余
    Input
    输入包含多组测试数据每组测试
    数据一行两个整数 n,p
    Output
    对于每组测试数据输出一行表示答案
    3 5

    4
    2 233

    0
    Hint
    设数据组数为 T
    对于 10%的数据,n<=10,p<=1000,T=1
    对于另外 10%的数据,n<=12,p<=1000,T<=12
    对于另外 10%的数据,n<=100,p<=100000,T<=100
    对于另外 10%的数据,n<=100000,p<=1000000,T=1
    对于另外 10%的数据,n<=100000,p<=1000000,T<=1000
    对于另外 20%的数据,n<=1e9,p<=1e9,T<=1000
    对于 100%的数据,n<=1e18,p<=1e18,T<=1000

    找规律 

    对于3 我们可以找出所有情况 

    1 3 2

    2 3 1

    2 1 3

    3 1 2

    我们可以发现 4的所有递增递减的情况一定是基于3的所有情况 

     1 3 2   我们可以将4放在 3前面 1 4 3 2 或者 放在3后面 1 3 4 2 

    其他情况相同 n全排列的单峰情况 一定可以由n-1的单峰排列情况推出 

    共2的n次方种

    但这不是全部  

    还有特殊情况 1 2 3  -->1 2 4 3

              -->4 1 2 3   

           3 2 1  -->3 4 2 1

              -->3 2 1 4   

    共 2n+4种

    2n用快速幂和快速乘即可

     1 #include <cstdio>
     2 #include <cctype>
     3 #include <algorithm>
     4 
     5 typedef long long LL;
     6 
     7 using namespace std;
     8 
     9 int T;
    10 
    11 LL n,p;
    12 
    13 inline void read(LL&x) {
    14     int f=1;register char c=getchar();
    15     for(x=0;!isdigit(c);c=='-'&&(f=-1),c=getchar());
    16     for(;isdigit(c);x=x*10+c-48,c=getchar());
    17     x=x*f;
    18 }
    19 
    20 inline LL quick_plus(LL b,LL k) {
    21     LL ans=0;
    22     while(k) {
    23         if(k&1) ans=(ans+b)%p;
    24         k>>=1;
    25         b=(b+b)%p;
    26     }
    27     return ans%p;
    28 }
    29 
    30 inline LL quick_pow(LL a,LL k) {
    31     LL ans=1;
    32     while(k) {
    33         if(k&1) ans=quick_plus(ans,a);
    34         k>>=1;
    35         a=quick_plus(a,a);
    36     }
    37     return ans;
    38 }
    39 
    40 int hh() {
    41 //    freopen("permutation.in","r",stdin);
    42 //    freopen("permutation.out","w",stdout);
    43     while(~scanf("%lld%lld",&n,&p)) {
    44         if(n==1||n==2) {
    45             printf("0
    ");
    46             continue;
    47         }
    48         LL ans=quick_pow(2,n);
    49         LL L=4-p;
    50         ans=(ans-L+p)%p;
    51         printf("%lld
    ",ans);
    52     }
    53     return 0;
    54 }
    55 
    56 int sb=hh();
    57 int main(int argc,char**argv) {;}
    代码
  • 相关阅读:
    观察者模式
    系统高并发网络图书室
    java keytool
    ant 脚本使用技巧
    Unsupported major.minor version 51.0 错误解决方案
    Oracle的网络监听配置
    win8 JDK环境变量不生效
    javax.mail
    xmlrpc
    网络时间同步
  • 原文地址:https://www.cnblogs.com/whistle13326/p/7515014.html
Copyright © 2020-2023  润新知