zoukankan      html  css  js  c++  java
  • 2018航电多校练习第9场-快速幂

    Rikka with Badminton

    Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 524288/524288 K (Java/Others)
    Total Submission(s): 53    Accepted Submission(s): 44

    Problem Description

    In the last semester, Rikka joined the badminton club.

    There are n students in the badminton club, some of them have rackets, and some of them have balls. Formally, there are a students have neither rackets nor balls, bstudents have only rackets, c students have only balls, and d students have both rackets and balls. (a+b+c+d=n)

    This week, the club is going to organize students to play badminton. Each student can choose to take part in or not freely. So there are 2n possible registration status. 

    To play badminton, there must be at least two students who have rackets and at least one students who have balls. So if there aren't enough balls or rackets, the activity will fail. 

    Now, Rikka wants to calculate the number of the status among all 2n possible registration status which will make the activity fail.

    Input

    The first line contains a single number t(1≤t≤103), the number of testcases.

    For each testcase, the first line contains four integers a,b,c,d(0≤a,b,c,d≤107,a+b+c+d≥1).

    Output

    For each testcase, output a single line with a single integer, the answer modulo 998244353.

    Sample Input

    3

    1 1 1 1

    2 2 2 2

    3 4 5 6

    Sample Output

    12

    84

    2904

    题意:

    给你a,b,c,d四种人的人数:分别代表什么都没有,一个拍,一个球,一个球一个拍

    问你有多少种可能连一个球两个拍都没有

    a不需要讨论

    当d取1时,b必须为0,c随便取:(fun(2,a)%maxx * fun(2,c)%maxx) *d %maxx;

    当d取0时,b取1或0,c随便取:(fun(2,a)%maxx * (b+1)%maxx)*fun(2,c)%maxx;

    当d取0时,b取0或1以外的数,c必须为0:(fun(2,a)%maxx * (fun(2,b)-b-1+maxx)%maxx)%maxx;

    三种情况相加,输出时还要取模

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 typedef long long ll;
     4 #define maxx 998244353
     5 
     6 ll fun(ll a,ll b){  
     7 ll r = 1;
     8 while(b){
     9         if(b&1){
    10                 r = (r*a)%maxx;
    11         }
    12         a = (a*a)%maxx;
    13         b>>=1;
    14 }
    15 return r;
    16 }
    17 int main(){
    18 int T;
    19 while(scanf("%d",&T)!=EOF){
    20       while(T--){
    21             ll a,b,c,d;
    22             scanf("%lld%lld%lld%lld",&a,&b,&c,&d);
    23             ll ans = 0;
    24             ans += (fun(2,a)%maxx * fun(2,c)%maxx) *d %maxx;
    25             ans += (fun(2,a)%maxx * (b+1)%maxx)*fun(2,c)%maxx;
    26             ans += (fun(2,a)%maxx * (fun(2,b)-b-1+maxx)%maxx)%maxx;
    27             printf("%lld
    ",ans%maxx);
    28       }
    29 }
    30 return 0;
    31 }

    乘法取模:

    (a*b)%mod = ((a%mod) * (b*mod)) % mod

    除法取模:

    费马小定理:若p是质数,且a、p互质,那么a^(p-1) mod p = 1。
    现在,我们要求a/c mod p,通过一系列神奇的转化,那万恶的除法就会神奇地消失...
    a / c mod p
    = a / c mod p * 1
    = a / c mod p * c^(p-1) mod p
    = a * c^(p-2) mod p

    快速幂:

    乘法在计算机中处理的时间并不是这么快的,也要拆分为加法来做的。所以快速乘法会更快的计算a*b的结果,而且a*b%mod可能还没取模就已经爆long long,但快速乘法却不会。快速幂也是同样的道理。
    实现的原理都是基于按照二进制位一步一步乘来避免重复的操作,利用前面的中间结果,从而实现快速的目的。
    对于乘数b来说,势必可以拆成2进制,比如110101。有一些位为0,有一些位为1。根据乘法分配律:a*b=a*(b1+b2+b3+……) 那么对于a*53 = a*110101(二进制)= a*(100000+10000+100+1)=a*(100000*1+10000*1+1000*0+100*1+10*0+1*1)。 那么设立一个ans=0用于保存答案,每一位让a*=2,在根据b的对应为1看是不是加上此时的a,即可完成快速运算。

    long long q_mul( long long a, long long b, long long mod ) //快速计算 (a*b) % mod 
    {
        long long ans = 0;           // 初始化
        while(b)                     //根据b的每一位看加不加当前a
        {
            if(b & 1)                //如果当前位为1
            {
                b--;
                ans =(ans+ a)%mod;   //ans+=a
            }
            b >>= 1;                 //b向前移位
            a = (a + a) % mod;       //更新a
     
        }
        return ans;
    }
    long long q_pow( long long a, long long b, long long mod ) //快速计算 (a^b) % mod
    {
        long long ans = 1;                       // 初始化
        while(b)                                 //根据b的每一位看乘不乘当前a
        {
            if(b & 1)                            //如果当前位为1
            {
                ans = (ans*a)%mod                //ans*=a
            }
            b >>= 1;                             //b向前移位
            a = (a*a)%mod;                       //更新a
        }
        return ans;
    }

     

  • 相关阅读:
    单点登录实现机制:web-sso
    阿里云API网关(16)客户端请求的https支持
    阿里云API网关(15)监控预警
    BZOJ1802: [Ahoi2009]checker(性质分析 dp)
    LOJ#505. 「LibreOJ β Round」ZQC 的游戏(最大流)
    LOJ#6085. 「美团 CodeM 资格赛」优惠券(set)
    洛谷P3924 康娜的线段树(期望 前缀和)
    BZOJ2337: [HNOI2011]XOR和路径(期望 高斯消元)
    2016计蒜之道复赛 百度地图的实时路况(Floyd 分治)
    洛谷P2881 [USACO07MAR]排名的牛Ranking the Cows(bitset Floyd)
  • 原文地址:https://www.cnblogs.com/mxj961116/p/9508830.html
Copyright © 2011-2022 走看看