2016 ICPC大连站---F题 Detachment
2018-06-17 23:39:50来源:未知 阅读 ()
题意:输入一个x,将x拆分成一些小的数(这些数不能相同,即x=a1+a2+...... ai!=aj when i!=j),然后这些数相乘得到一个成积(s=a1*a2*......),求最大的乘积s;
思路:考虑最简单的做法便是贪心,很明显将一个数分的越小,这个乘积越大,那么对于给的x 先找2+3+4+....+n<=x 找到最大的n 如果和小于x ,那么将n右移一个数(n->n+1) 如果和还小于x继续将n-1右移......知道和x相等时,输出s 这样做时间复杂度很高,那么得优化。 由上面的过程分析发现,2+3+...+n<=x &&2+3+...+n+(n+1)>x
那么x-(2+3+...+n)<=n 那么最终x分成的数结果只有三种情况:x=2+3+...+(k-1)+(k+1)+...+n+(n+1) x=3+4+...+n+(n+1) x=3+4+...+(n-1)+n+(n+2)
其实第一种和第二种情况相同。 分析过程如上,详细计算过程如下:2+3+...+n<=x 所以n*(n+1)<=2*x+2 n<=sqrt(2*n+2)
代码如下:
#include <iostream> #include <algorithm> #include <cstdio> #include <cstring> #include <cmath> #include <bitset> using namespace std; typedef long long LL; const LL mod=1e9+7; const LL maxn=1e5+5; LL A[maxn],s[maxn]; LL Inv[maxn]; void getINV()///逆元; { Inv[1]=1; for(LL i=2; i<maxn; i++) Inv[i] = (mod-mod/i)*Inv[mod%i]%mod; } void init() { s[1]=0; for(LL i=2;i<maxn;i++) s[i]=s[i-1]+i; A[0]=1; for(LL i=1;i<maxn;i++) A[i]=A[i-1]*i%mod; getINV(); } int main() { init(); int T; cin>>T; while(T--) { int pos; LL x,sum; scanf("%lld",&x); LL n=(LL)(sqrt(2*x+2)); for(int i=n;i>=1;i--) if(s[i]<=x){ pos=i; break; } if(x==1) { puts("1"); continue; } if(s[pos]==x) { printf("%lld\n",A[pos]); continue; } if(s[pos]+pos-1>=x){ LL tot=s[pos]+pos-1-x; sum=(A[pos+1]*Inv[tot+2])%mod; } else{ LL tot=s[pos+1]-2+pos-1-x; sum=((A[pos+2]*Inv[2])%mod)*Inv[tot+3]%mod; } printf("%lld\n",sum); } return 0; }
标签:
版权申明:本站文章部分自网络,如有侵权,请联系:west999com@outlook.com
特别注意:本站所有转载文章言论不代表本站观点,本站所提供的摄影照片,插画,设计作品,如需使用,请与原作者联系,版权归原作者所有
上一篇:内存分为的5大区
- 2020年3月28日UCF Local Programming Contest 2016 2020-03-31
- 洛谷P4071-[SDOI2016]排列计数 题解 2020-01-12
- 2019 ICPC 银川站 2019-12-11
- 统计字符的个数,能够组成几个acmicpc 2019-10-16
- [NOIP2016]天天爱跑步-题解 2019-10-08
IDC资讯: 主机资讯 注册资讯 托管资讯 vps资讯 网站建设
网站运营: 建站经验 策划盈利 搜索优化 网站推广 免费资源
网络编程: Asp.Net编程 Asp编程 Php编程 Xml编程 Access Mssql Mysql 其它
服务器技术: Web服务器 Ftp服务器 Mail服务器 Dns服务器 安全防护
软件技巧: 其它软件 Word Excel Powerpoint Ghost Vista QQ空间 QQ FlashGet 迅雷
网页制作: FrontPages Dreamweaver Javascript css photoshop fireworks Flash