湘潭-1203-A simple problem
地址:http://202.197.224.59/OnlineJudge2/index.php/Problem/read/id/1203
做法:
假如n等于10^12。
那么n%1...n%10^6暴力解。复杂度o(10^6)
对于随意的n%x=y;
得: x*t+y=n;(t>=1&&t<=sqrt(n))
对于随意的t,
第一个x*t+y=n的x1为n/(t+1)+1;
最后一个x*t+y=n的x2为n/t;
n%x1,n%(x1+1),n%(x1+2)......n%(x2)的结果形成一个等差数列。
所以这个数列的y的和能够用等差数列求前n项和求出来。
注意超LL范围了。。用大数吧。。。
而且大数还得优化一下。
让大数的每一位尽量取大一点。
#include<stdio.h> #include<string.h> #include<algorithm> #include<iostream> #include<vector> using namespace std; #define LL __int64 #define jin 1000000 struct BIGnumber { LL num[101]; int len; void getnum(LL x) { len=0; if(x==0) { num[len++]=0; return; } while(x) { num[len++]=x%jin; x=x/jin; } } void add(LL x) { int st=0; // cout<<"______"<<endl; while(x) { if(st>=len) { num[len++]=0; } num[st]+=x%jin; x=x/jin; x=x+num[st]/jin; num[st]=num[st]%jin; //cout<<num[st]<<" "<<x<<" "<<st<<" "<<len<<endl; st++; } } void add(BIGnumber a) { int lenx=a.len,i; LL x,leap; x=leap=0; for(i=0;i<lenx&&i<len;i++) { x=num[i]+a.num[i]+leap; num[i]=x%jin; leap=x/jin; } while(i<lenx) { if(i>=len)num[len++]=0; x=a.num[i]+leap; num[i]+=x%jin; leap=x/jin; i++; } while(i<len) { x=num[i]+leap; num[i]=x%jin; leap=x/jin; i++; } while(leap) { if(i>=len)num[len++]=0; num[i++]=leap%jin; leap=leap/jin; } } void mul(LL b) { if(b == 0) { len=1; num[0]=0; return; } LL x=0; LL leap=0; for(int i=0;i<len;i++) { x=num[i]*b+leap; num[i]=x%jin; leap=x/jin; } while(leap) { num[len++]=leap%jin; leap=leap/jin; } } void print() { for(int i=len-1; i>=0; i--) { if(i!=len-1)printf("%06I64d",num[i]); else printf("%I64d",num[i]); } } } sum,nn; LL dos(LL x) { LL s=0; for(int i=1;i<=x;i++) { s+=x%i; } return s; } int main() { // freopen("data.in","r",stdin); // freopen("data1.out","w",stdout); int T; LL n,x,y; LL a,b,l; scanf("%d",&T); int cas=0; while(T--) { cas++; scanf("%I64d",&n); sum.getnum(0); x=y=n; for(int i=1; i<n; i++) { x=n/i; y=n/(i+1)+1; if(x<=y)break; a=n%x+n%y; l=x-y+1; if(a%2)l=l/2; else a=a/2; nn.getnum(a); nn.mul(l); sum.add(nn); } /// cout<<sum.len<<endl; for(int i=1; i<=x; i++) { sum.add(n%i); } //cout<<sum.len<<endl; printf("Case %d: ",cas); sum.print(); puts(""); } return 0; }