hdu 5187 阴险的爆掉long long
BestCoder第33场上的第二题,表示虽然推出了公式,即:
对于n = 1时,ans = n % p(因为p可能为1,所以不能直接写ans = 1);
对于n > 1时,ans = 2 ^ n - 2。
具体公式的推法这里引用出题人laekov的原话:
对,没错,就是因为p是2的31次幂,当直接采用快速幂的话,会超long long。1002 zhx and contest 如果n=1 ,答案是1 ,否则答案是2n−2 。 证明:ai 肯定是最小的或者最大的。考虑另外的数,如果它们的位置定了的话,那么整个序列是唯一的。 那么ai 是最小或者最大分别有2n−1 种情况,而整个序列单调增或者单调减的情况被算了2次,所以要减2。 要注意的一点是因为p>231 ,所以要用快速乘法。用法与快速幂相同。如果直接乘会超过long long范围,从而wa掉。
【于是就都是眼泪了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;
}

浙公网安备 33010602011771号