hdu 5187 阴险的爆掉long long

来源:互联网 发布:淘宝代运营十大排名 编辑:程序博客网 时间:2024/05/01 13:50

BestCoder第33场上的第二题,表示虽然推出了公式,即:

对于n = 1时,ans = n % p(因为p可能为1,所以不能直接写ans = 1);

对于n > 1时,ans = 2 ^ n - 2。

具体公式的推法这里引用出题人laekov的原话:
1002 zhx and contest如果n=1,答案是1,否则答案是2n2。证明:ai肯定是最小的或者最大的。考虑另外的数,如果它们的位置定了的话,那么整个序列是唯一的。那么ai是最小或者最大分别有2n1种情况,而整个序列单调增或者单调减的情况被算了2次,所以要减2。要注意的一点是因为p>231,所以要用快速乘法。用法与快速幂相同。如果直接乘会超过long long范围,从而wa掉。
对,没错,就是因为p是2的31次幂,当直接采用快速幂的话,会超long long。
【于是就都是眼泪了TAT~,总之还是太年轻】
AC代码:
#include <iostream>#include <cstdio>using namespace std;typedef long long LL;inline LL Fast_mult(LL x, LL y, LL p) {    LL t=0;    for(; y; y>>=1,x=(x+x)%p)        if(y&1)t=(t+x)%p;    return t;}inline LL power(LL x, LL y, LL p) {    LL t=1;    for(; y; y>>=1,x=Fast_mult(x,x,p)%p)        if(y&1)t=Fast_mult(t,x,p);    return t;}int main() {    LL n, p;    while(~scanf("%I64d%I64d", &n, &p)) {        if(n == 1) printf("%I64d\n", n % p);        else printf("%I64d\n",(power(2, n, p) - 2 + p) % p);    }    return 0;}


0 0