题目大意:
给定一个奇质数
p
和序列
分析:
将序列分为
A={1...p},B={p+1...2p}
,除去全选
A or B
有两种方案,两边都选的共有
Cp2p−2
种情况。
考虑这些情况中的任意一种,设和为
k (mod p)
,且选了
B
中
综上,答案为
Cp2p−2p+2
。
AC code:
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int MAXP = 1009;
const int MOD = 1e5;
struct bi
{
int a[1009];
bi()
{
memset(a, 0, sizeof a);
a[0] = 1;
}
void operator += (int b)
{
int i = 1;
a[i] += b;
while(a[i] >= MOD)
{
a[i+1] += a[i]/MOD;
a[i++] %= MOD;
}
a[0] = max(a[0], i);
}
void operator -= (int b)
{
int i = 1;
a[i] -= b;
while(a[i] < 0)
{
a[i+1]--;
a[i++] += MOD;
}
while(!a[a[0]]) a[0]--;
if(!a[0]) a[0] = 1;
}
void operator *= (int k)
{
for(int i = 1; i <= a[0]; ++i)
a[i] *= k;
for(int i = 1; i <= a[0]; ++i)
{
a[i+1] += a[i]/MOD;
a[i] %= MOD;
}
while(a[a[0]+1])
{
a[0]++;
a[a[0]+1] += a[a[0]]/MOD;
a[a[0]] %= MOD;
}
}
void operator /= (int k)
{
for(int i = a[0]; i >= 1; --i)
{
a[i-1] += a[i]%k*MOD;
a[i] /= k;
}
while(!a[a[0]]) a[0]--;
if(!a[0]) a[0] = 1;
}
void print()
{
printf("%d", a[a[0]]);
for(int i = a[0]-1; i >= 1; --i)
printf("%05d", a[i]);
}
};
int main()
{
#ifndef ONLINE_JUDGE
freopen("input.txt", "r", stdin);
freopen("output.txt", "w", stdout);
#endif
int Test;
scanf("%d", &Test);
while(Test--)
{
int p;
scanf("%d", &p);
bi ans;ans.a[1] = 1;
for(int i = 2*p; i >= p+1; --i)
ans *= i, ans /= 2*p-i+1;
ans -= 2, ans /= p, ans += 2;
ans.print(), puts("");
}
#ifndef ONLINE_JUDGE
fclose(stdin);
fclose(stdout);
#endif
return 0;
}