首页 > 代码库 > 湘潭-1203-A simple problem

湘潭-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;
}