zoukankan      html  css  js  c++  java
  • Asm.Def点大兵

    syzoj上的题,收货很多,orz天天学长

    原题:

    Asm.Def奉命组建一支m人的特种作战小队前往圣迭戈。他有n名候选人,可以在其中任意挑选。由于小队中每个人都有独特的作用,所以次序不同的两种选法被认为是不同的方案。由于方案数可能非常大,Asm.Def只需要知道它模p的值。

    100%:n<=10^18,m<=10^5,p<=10^18

    很明显就是求排列……

    然而n<=10^18用longlong乘的话会炸

    用高精度的话取模会非常不好搞,而且常数似乎也不滋瓷

    syzoj可以直接查看别人代码,然后就看到了这么个黑科技:

     1 LL f(LL x,LL y)
     2 {
     3     LL tmp=0;
     4     while(y)
     5     {
     6         if(y&1)
     7             tmp=(tmp+x)%p;
     8         y=y>>1;
     9         x=(x<<1)%p;
    10     }
    11     return tmp;
    12 }
    View Code

    一眼看上去挺像快速幂的,看不懂,请教天天学长

    然后就知道这是为了防止炸longlong的二进制分配乘

    原理就是将其中一个乘数分解成二进制,比如5 * 17就是5 * (16 + 1),5 * 23 就是 5 * (16 + 4 + 2 + 1)

    逐步膜就不会炸longlong

    新姿势get√

    还要再强调一下,如果使用longlong就要逐步走一遍,所有遇到的变量全部换成longlong,尤其是函数的参数和返回值,有时候甚至循环变量也会使用longlong,比如for(long long i=n-m+1;i<=n;i++),其中n,m都是longlong

    代码:

     1 //__3_108_120_116__
     2 #include<iostream>
     3 #include<cstdio>
     4 #include<algorithm>
     5 #include<cstring>
     6 #include<cmath>
     7 using namespace std;
     8 long long m,n,mo;
     9 long long ans=1;
    10 long long multiply01(long long x,long long y){//参数传的是longlong!!!
    11     long long z=0;
    12     while(y){
    13         if(y&1)  z=(z+x)%mo;
    14         y=y>>1;
    15         x=(x<<1)%mo;
    16     }
    17     return z;
    18 }
    19 int main(){
    20     cin>>n>>m>>mo;
    21     for(long long i=n-m+1;i<=n;i++)//要注意这里n会很大所以i要longlong!
    22         ans=multiply01(ans,i);
    23     cout<<ans<<endl;
    24     return 0;
    25 }
    View Code
  • 相关阅读:
    系统管理命令之tty
    系统管理命令之id
    idea中使用junit测试时使用Scanner类无法正常测试
    002-字段不为null
    java8中接口中的default方法
    java之接口适配器
    java之对象适配器
    java之类适配器
    java之多态(六)
    java之多态(五)
  • 原文地址:https://www.cnblogs.com/JSL2018/p/6047137.html
Copyright © 2011-2022 走看看