zoukankan      html  css  js  c++  java
  • TYVJ P1651

    背景 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("
    ");
    	for (int j=i+1;j<=maxl;j++)
    	{
    		printf("%08lld",a[j]);
    		if (j==maxl)
    			printf("
    ");
    	}
    }
    
    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
    ",(6*kk*nn-kk*kk*kk*2-kk*kk*3+5*kk)/6);
    	printf("kn6:%d
    ",6*kk*nn);
    	printf("kkk2:%d
    ",kk*kk*kk*2);
    	printf("kk3:%d
    ",kk*kk*3);
    	printf("k5:%d
    ",kk*5);
    	printf("1 step:%d
    ",6*kk*nn+kk*5);
    	printf("%d
    ",6*kk*nn+kk*5-kk*kk*kk*2);
    	printf("%d
    ",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;
    }
    
  • 相关阅读:
    5个步骤迅速脱离低薪族
    phpdebugapd调试器
    重置zend studio 默认设置的方法
    CMD用什么命令可以删除服务?
    PHP自动识别字符集并完成转码
    一只赖蛤蟆写给白天鹅的情书
    遇到的问题
    Sql 注入漏洞
    分页技术
    flex学习记录——加载图片
  • 原文地址:https://www.cnblogs.com/cssystem/p/3170643.html
Copyright © 2011-2022 走看看