HDU3049
题目描述:
Chinachen is a football fanatic, and his favorite football club is Juventus fc. In order to buy a ticket of Juv, he finds a part-time job in Professor Qu’s lab.And now, Chinachen have received an arduous task——Data Processing.
The data was made up with N positive integer (n1, n2, n3, … ), he may calculate the number , you can assume mod N =0. Because the number is too big to count, so P mod 1000003 is instead.
Chinachen is puzzled about it, and can’t find a good method to finish the mission, so he asked you to help him.
一道非常简单的求逆元的题,主要是写一下新学的O(n)时间内打出1~N的逆元表的技巧。2^N的模数可以先打好表,每次查询就是O(1)的时间。
逆元表的打法: inv[i] = - k * inv[r] (mod p) (其中 k = p/i r = p%r)
证明: p = k*i + r
0 = k*i + r (mod p)
0 = k*inv[r] + inv[i] (mod p)
新学到负数求模数 = (x%p + p)%p
#include<cstdio>
#include<iostream>
using namespace std;
typedef long long ll;
int T;
const int MOD = 1000003;
const int SIZE = 40005;
ll expn[SIZE];
ll inv[SIZE];
ll N;
void getinv()
{
inv[1] = 1;
for(int i=2;i<SIZE;i++)
{
ll k = MOD / i;
ll r = MOD % i;
ll in = - k * inv[r];
inv[i] = (in%MOD+MOD)%MOD;
}
}
int main()
{
getinv();
expn[1] = 2;
for(int i=2;i<=40000;i++)
expn[i] = expn[i-1]*2%MOD;
int T;
cin >> T;
int cs = 1;
while(T--)
{
cin >> N;
ll n;
ll sum = 0;
for(int i=1;i<=N;i++)
{
scanf("%I64d",&n);
sum += expn[n];
sum %= MOD;
}
sum *= inv[N];
sum %= MOD;
printf("Case %d:%lld\n",cs++,sum);
}
return 0;
}