BZOJ 1416: [NOI2006]神奇的口袋( 高精度 )
把x1~xn当成是1~n, 答案是不会变的. 然后直接模拟就行了......
P.S 双倍经验... BZOJ1416 && BZOJ1498
-------------------------------------------------------------------------------
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int maxn = 20009;
int a[maxn], t, n, d, tot;
int p[maxn], pn, cnt0[maxn], cnt1[maxn];
bool F[maxn];
void Init() {
memset(F, 0, sizeof F);
pn = 0;
for(int i = 2; i < maxn; i++) {
if(!F[i])
p[pn++] = i;
for(int j = 0; i * p[j] < maxn; j++) {
F[i * p[j]] = true;
if(i % p[j] == 0) break;
}
}
}
int buf[10000];
void calc(int h[]) {
memset(buf, 0, sizeof buf);
buf[0] = 1;
int L = 1;
for(int i = 0; i < pn; i++)
for(int j = 0; j < h[i]; j++) {
for(int k = 0; k < L; k++) buf[k] *= p[i];
for(int k = 0; k < L; k++) if(buf[k] > 9) {
buf[k + 1] += buf[k] / 10;
buf[k] %= 10;
}
for(; buf[L] > 0; L++) if(buf[L] > 9) {
buf[L + 1] += buf[L] / 10;
buf[L] %= 10;
}
}
while(L--)
putchar(buf[L] + '0');
}
void mult(int x, int h[]) {
for(int i = 0; i < pn; i++) if(x % p[i] == 0)
for(; x % p[i] == 0; x /= p[i]) h[i]++;
}
int main() {
Init();
scanf("%d%d%d", &t, &n, &d);
for(int i = 1; i <= t; i++) {
scanf("%d", a + i);
tot += a[i];
}
while(n--) {
int x, y;
scanf("%d%d", &x, &y);
mult(a[y], cnt0);
mult(tot, cnt1);
tot += d, a[y] += d;
}
for(int i = 0; i < pn; i++) if(cnt1[i] >= cnt0[i])
cnt1[i] -= cnt0[i], cnt0[i] = 0;
else if(cnt1[i] < cnt0[i])
cnt0[i] -= cnt1[i], cnt1[i] = 0;
calc(cnt0);
putchar('/');
calc(cnt1);
return 0;
}
-------------------------------------------------------------------------------
1416: [NOI2006]神奇的口袋
Time Limit: 10 Sec Memory Limit: 64 MBSubmit: 410 Solved: 268
[Submit][Status][Discuss]
Description
Input
Output
0/1,概率为1 应输出1/1。
Sample Input
input 1
2 3 1
1 1
1 1
2 2
3 1
input 2
3 1 2
1 1 1
5 1
2 3 1
1 1
1 1
2 2
3 1
input 2
3 1 2
1 1 1
5 1
Sample Output
output 1
1/12
output 2
1/3
1/12
output 2
1/3
HINT
1≤t,n≤1000, 1≤ak ,d≤10, 1≤x1
Source