• hdu 5187 快速幂 + 快速乘 值得学习


    就是以那个ai为分水岭,左边和右边都分别是单调增或单调减如图

            就这四种情况,其中头两种总共就是两个序列,也就是从头到尾递增和从头到尾递减。

            后两种方式就是把序列中德数分为左右两派,分完以后左右两边各自内部的排法就已经确定了,至于ai早就确定了(不是全局最大就是全局最小),而除了ai的每一个数都有选择在左或是在右两种选择,所以是2^(n-1),总共就是2^n,而这里包括了前两种的方案,所以要-4,最终应有2^n-2种。

            看数据范围就知道要用快速幂,不过可惜如果只用快速幂会错,应为n和p的范围都是10^18,快速幂里在还没有模p之前的乘法都有可能超出long long int。所以想到用加法,a*b就是b个a相加,每一步都模p,8个a相加 =c  c+c = 16个a 相加, 和快速幂一个道理。  然后用快速幂的原理不断二分,这就是所谓的快速乘法。

            还有就是特殊数据,当n输入为1的时候情况数不是0而是1,当然不像BC上说的那样结果就是1,而是1MODp。

     1 //
     2 //  main.cpp
     3 //  hdu5187
     4 //
     5 //  Created by opas on 15/3/18.
     6 //  Copyright (c) 2015年 opas. All rights reserved.
     7 //
     8 
     9 #include <iostream>
    10 #include <cstdio>
    11 #include <string.h>
    12 using namespace std;
    13 typedef long long  LL;
    14 LL modj(LL a, LL b, LL m){
    15     LL ans=0;
    16     while(b){
    17         if(b&1) ans=(ans+a)%m;
    18         b>>=1;
    19         a=(a+a)%m;
    20     }
    21     return ans;
    22 }
    23 LL modx(LL a, LL b, LL m){
    24     LL ans=1;
    25     while(b){
    26         if(b&1)ans=modj(ans,a,m);
    27         b>>=1;
    28         a = modj(a,a,m);
    29     }
    30     return ans;
    31 }
    32 int main(int argc, const char * argv[]) {
    33     LL n,p;
    34     while(scanf("%lld%lld",&n,&p)==2){
    35         if(n==1){
    36             printf("%d
    ",p>1?1:0); continue;
    37         }
    38         printf("%lld
    ",(  modx( 2, n, p ) -2+p)%p );
    39     }
    40     return 0;
    41 }
  • 相关阅读:
    基于PyQt4.QtWebKit的浏览器模拟类
    Unit Testing Struts 2 Actions wired with Spring using JUnit
    formExtractor: 在QtWebkit的javascript访问QObject的例子
    更改terminal下显示的主机名称
    访问ssh不用密码
    WebKit in Qt
    QtWebKit based Web Browser
    测试Action
    struts2+mybatis+spring框架整合
    礼品卡
  • 原文地址:https://www.cnblogs.com/Opaser/p/4348988.html
Copyright © 2020-2023  润新知