【BZOJ 1005】[HNOI2008]明明的烦恼(化简的另一种方法)
2017-10-04 18:45
183 查看
【题目链接】:http://www.lydsy.com/JudgeOnline/problem.php?id=1005
【题意】
【题解】
题目和题解在上一篇;
这里 对
【(m^(n-2-tot))* (n-2)!】/【(n-2-tot)!* (d[1]-1)!*(d[2]-1)!……(d
-1)!】;
这个式子的化简再说一个方法;
对于n!
最后分解成质因子的时候;
质因子p的指数应该为
∑(n/i);
这里i为p,p^2,p^3….p^x,且p^x<=n
这样;
因为最大要求的阶乘为(n-2)!
所以先处理出2..n-2之间哪些数是质数;
然后对于x!
直接枚举2..x之间的那些质数;
然后i=p,p平方,p立方,p的4次方..那样加上n/i;
知道某个质数的指数之后,直接根据是分子还是分母,分别加上或减去那个∑(n/i)就好;
这样就不用1..x里面每个数都再去分解一次质因数了;
//直接暴力搞 for (int i = 1;i <= x;i++) { int x = i; for (int j= 2;j*j <= x;j++) while (x%j==0) { cnt[j]->change; x/=j; } }
//更优雅的方法 for (int i = 2;i <= x;i++) { if (zhishu[i]) { zhi=0 for (int j = i;j <= x;;j*=i) zhi+=x/j; cnt[i]->change(zhi); } }
【完整代码】
/************************************************************** Problem: 1005 User: chengchunyang Language: C++ Result: Accepted Time:36 ms Memory:1316 kb ****************************************************************/ #include <bits/stdc++.h> using namespace std; #define lson l,m,rt<<1 #define rson m+1,r,rt<<1|1 #define LL long long #define rep1(i,a,b) for (int i = a;i <= b;i++) #define rep2(i,a,b) for (int i = a;i >= b;i--) #define mp make_pair #define pb push_back #define fi first #define se second #define rei(x) scanf("%d",&x) #define rel(x) scanf("%I64d",&x) typedef pair<int,int> pii; typedef pair<LL,LL> pll; const int dx[9] = {0,1,-1,0,0,-1,-1,1,1}; const int dy[9] = {0,0,0,-1,1,-1,1,-1,1}; const double pi = acos(-1.0); const int N = 1100; int n,d ,m,tot,cnt ; int ans ,len = 1; bool bo ; void go(int t,int x) { rep1(i,2,t) if (bo[i]) { int num = 0; for (int j = i;j <= t;j*=i) num+=t/j; cnt[i]+=x*num; } } void cheng(int p) { int x = 0; rep1(i,1,len) { ans[i] = ans[i]*p+x; x = ans[i]/10; ans[i]%=10; } while (x>0) { ans[++len] = x; x = ans[len]/10; ans[len]%=10; } } bool is(int x) { rep1(i,2,int(sqrt(x))) if (x%i==0) return false; return true; } int main() { //freopen("F:\\rush.txt","r",stdin); rei(n); rep1(i,1,n) { rei(d[i]); if (d[i]==0) return puts("0"),0; if (d[i]==-1) m++; else d[i]--,tot+=d[i]; } if (n-2<tot) return puts("0"),0; memset(bo,false,sizeof bo); rep1(i,2,n-2) if (is(i)) bo[i] = true; go(n-2,1); go(n-2-tot,-1); rep1(i,1,n) go(d[i],-1); ans[1] = 1; rep1(i,2,n) rep1(j,1,cnt[i]) cheng(i); rep1(i,1,n-2-tot) cheng(m); rep2(i,len,1) printf("%d",ans[i]); return 0; }
相关文章推荐
- 【BZOJ 1005】[HNOI2008]明明的烦恼(暴力化简法)
- 【BZOJ 1005】 1005: [HNOI2008]明明的烦恼 (prufer数列+高精度)
- BZOJ.1005.[HNOI2008]明明的烦恼(Prufer 高精 排列组合)
- 【BZOJ1005】【HNOI2008】明明的烦恼
- BZOJ1005 [HNOI2008]明明的烦恼
- bzoj 1005: [HNOI2008]明明的烦恼
- 【bzoj1005】[HNOI2008]明明的烦恼
- 【bzoj1005】[HNOI2008]明明的烦恼
- bzoj 1005: [HNOI2008]明明的烦恼
- BZOJ 1005 [HNOI2008]明明的烦恼 Prufer序列 Python
- 【BZOJ】1005: [HNOI2008]明明的烦恼(prufer编码+特殊的技巧)
- [bzoj1005][HNOI2008]明明的烦恼
- 【BZOJ1005】明明的烦恼(HNOI2008)-Prufer序列+组合计数+高精度
- BZOJ1005: [HNOI2008]明明的烦恼
- 【组合数学】【高精度】【prufer数列】【HNOI 2008】【bzoj 1005】明明的烦恼
- bzoj1005【hnoi2008】明明的烦恼
- [BZOJ1005](HNOI 2008)明明的烦恼
- bzoj 1005: [HNOI2008]明明的烦恼
- [Prufer数列] BZOJ1005: [HNOI2008]明明的烦恼
- BZOJ 1005 [HNOI2008]明明的烦恼