【数学水题】【TOJ4113】【 Determine X】
题目大意:
yuebai has a long sequence of integers
He also has such a function:
Now he wants to know the minimum value of the function. 求一个x 使F[x]最大
解:
从1枚举到10^6
可知 当X超过10^6 方后 值就不变了
SB了
以为能快速求出的是sigma(Aimodx)。。。
发现 傻逼了 能快速求出的事 sigma(Aimodx)modx。。
预处理好a[i] 表示 A[i]中数值小于i的个数
以N/X的时间求出sigmafloor((Ai/x));
然后利用sigmafloor((Ai/x))+sigma(Aimodx)=sigma(Ai) 求出 sigma(Aimodx)
然后更新答案
代码如下:
#include <cstdio> #include <cstdlib> #include <cmath> #include <cstring> #include <ctime> #include <algorithm> #include <iostream> #include <sstream> #include <string> #define oo 0x13131313 using namespace std; const int maxn=1000000+5; int N; int A[maxn],a[maxn]; int MAX; long long sum=0; void input() { memset(A,0,sizeof(A)); memset(a,0,sizeof(a)); cin>>N; MAX=-1; sum=0; for(int i=1;i<=N;i++) { scanf("%d",&A[i]); a[A[i]]++; if(A[i]>MAX) MAX=A[i]; sum+=A[i]; } for(int i=1;i<=MAX;i++) { a[i]=a[i]+a[i-1]; } } void solve() { long long ans=1LL<<30; long long tt=0,g; for(int i=1;i<=MAX;i++) { int x=i;tt=0; for(int t=2*x;t-1<=MAX;t+=x) { int p=t-1; long long k=(long long)(a[p]-a[p-x])*(long long)(p/x); tt=tt+k; g=p; } tt=tt+(long long)(a[MAX]-a[g])*(long long)(MAX/x); tt=tt+sum-tt*(long long)x; if(tt<ans) ans=tt; } cout<<ans<<endl; } int main() { // freopen("a.in","r",stdin); int T; cin>>T; while(T--) { input(); solve(); } }