背景 Background
清北学堂杯Tyvj2周年邀请赛 第三道描述 Description
VNB从小立志当一名杰出的数学家。有一天,admin给了VNB一个任务:求int(√1)+int(√2)+……+int(√n)的值是多少。VNB 以为很简单,就接下了这个任务,但是当他看到n的范围大小就傻眼了。所以,他打着“节约计算用纸以保护地球”的口号向你发出了求救。注: int(x)表示实数x的整数部分。
再注:VNB怕你算太长时间,就先帮你算出了int(√n)的大小,来帮助你更好的完成此题。
输入格式 InputFormat
共两行每行一个正整数分别为N和 K,K表示int(√n)
输出格式 OutputFormat
仅一行一个正整数,为int(√1)+int(√2)+……+int(√n)的值。样例输入 SampleInput [复制数据]
10
3
样例输出 SampleOutput [复制数据]
19
数据范围和注释 Hint
30%的数据k<=2*10^6(保证结果在int64 or comp以内)
90%的数据k<=10^100
所有的数据保证k<=10^10000 k^2<=n<(k+1)^2
思路:这道题是我两年前用pascal写过的最长的一道题了,,但是当时还不会压位,最后一个点还T了,现在好多了,通项公式:ans=(6*k*n-2*k*k*k-3*k*k+5k)/6;
#include <cstdio>
#include <cstring>
#include <cstdlib>
using namespace std;
typedef long long ll;
const int maxn=4020,maxl=4000,ml=4010;
const ll mod=100000000;
ll a[ml],b[ml],c[ml],kn6[ml],six[ml],k[ml],n[ml],k2[ml];
ll ans[ml],kkk2[ml],kk3[ml],k5[ml],five[ml];
ll two[ml],three[ml];
ll t,add;
int h;
char kk[maxn*10],nn[maxn*10];
void close()
{
exit(0);
}
void mul(ll *a,ll *b,ll *c)
{
int reach;
for (reach=0;a[reach]==0 && reach<=maxl;reach++);
for (int i=maxl;i>=reach;i--)
{
h=i;
for (int j=maxl;j>=1;j--)
{
if (h==1) break;
t=a[i]*b[j];
c[h]+=t;
c[h-1]+=c[h] / mod;
c[h] %= mod;
h--;
}
}
}
void muls(ll *a,int v)
{
add=0;
for (int i=maxl;i>=1;i--)
{
t=add+a[i]*v;
a[i]=t % mod;
add=t / mod;
}
}
void plus(ll *a,ll *b,ll *c)
{
add=0;
for (int i=maxl;i>=1;i--)
{
t=a[i]+b[i]+add;
c[i]=t % mod;
add=t / mod;
}
}
void sub(ll *a,ll *b,ll *c)
{
add=0;
for (int i=maxl;i>=1;i--)
{
t=a[i]-b[i];
if (t<0)
{
a[i-1]--;
t+=mod;
}
c[i]=t;
}
}
void divide(int div,ll *a,ll *b)
{
t=0;add=0;
for (int i=1;i<=maxl;i++)
{
t=add * mod+a[i];
b[i]=t / div;
add=t % div;
}
}
void print(ll *a)
{
int i;
for (i=0;i<maxl && a[i]==0;i++);
printf("%lld",a[i]);
if (i==maxl) printf("\n");
for (int j=i+1;j<=maxl;j++)
{
printf("%08lld",a[j]);
if (j==maxl)
printf("\n");
}
}
void work()
{
mul(k,n,kn6);
muls(kn6,6);
/////////////////////
mul(k,k,kk3);
mul(kk3,k,kkk2);
muls(kkk2,2);
////////////////////
memset(a,0,sizeof(a));
muls(kk3,3);
////////////////////////
memcpy(k5,k,sizeof(k));
muls(k5,5);
/////////////////////
plus(kn6,k5,ans);
sub(ans,kkk2,ans);
sub(ans,kk3,ans);
divide(6,ans,ans);
print(ans);
/*
mul(k,n,kn6);
memset(six,0,sizeof(six));
six[maxl]=6;
mul(kn6,six,kn6);
print(kn6);
close();
//--------------------------
mul(k,k,kkk2);//k*k->kkk
mul(kkk2,k,kkk2);//k*k*k->kkk
two[maxl]=2;
mul(kkk2,two,kkk2);//2*k*k*k->kkk
//--------------------------
mul(k,k,kk3);//k*k->kk3
three[maxl]=3;
mul(kk3,three,kk3);//k*k*3->kk3
//-------------------------------
memset(five,0,sizeof(five));
five[maxl]=5;
mul(k,five,k5);//k*5->k5
//-------------------------------
plus(kn6,k5,ans);
sub(ans,kkk2,ans);
sub(ans,kk3,ans);
divide(6,ans,ans);
print(ans);
printf("Real Answer:%d\n",(6*kk*nn-kk*kk*kk*2-kk*kk*3+5*kk)/6);
printf("kn6:%d\n",6*kk*nn);
printf("kkk2:%d\n",kk*kk*kk*2);
printf("kk3:%d\n",kk*kk*3);
printf("k5:%d\n",kk*5);
printf("1 step:%d\n",6*kk*nn+kk*5);
printf("%d\n",6*kk*nn+kk*5-kk*kk*kk*2);
printf("%d\n",6*kk*nn+kk*5-kk*kk*kk*2-kk*kk*3);
*/
}
void convert(char *s,ll *b)
{
int l=strlen(s),rec=0;
h=maxl;
t=1;add=0;
for (int i=l-1;i>=0;i--)
{
rec++;
add+=t*(s[i]-'0');
t*=10;
if (rec==8)
{
rec=0;
b[h]=add;
add=0;
t=1;
h--;
}
}
if (add!=0) b[h]=add;
}
void init()
{
scanf("%s %s",nn,kk);
convert(nn,n);
convert(kk,k);
work();
}
int main ()
{
init();
close();
return 0;
}
浙公网安备 33010602011771号