码迷,mamicode.com
首页 > 其他好文 > 详细

2014湖南邀请赛

时间:2015-05-28 09:35:18      阅读:125      评论:0      收藏:0      [点我收藏+]

标签:数学   大数   

A题:

XTU 1203 A simple problem

第一次碰见这种卡常数的题。。。。。

刚开始用的long long发现还是不够,然后找了个大数模板

接下来就无限TLE,然后各种优化。。。。。

总结了下大数运算的几个优化要点

一、能不能大数的地方尽量少用大数

二、大数的数组开到够用就行,不要开太大

还有就是这道题的一个优化,暴力求前半部分的时候,可以把临界的数适当取大一点

/*
 * Author:        lj94093
 * Created Time:  2015/5/27 星期三 下午 5:30:26
 * File Name:     A simple problem.cpp
 */
#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<math.h>
using namespace std;
#define out(x) cout<<#x<<": "<<x<<endl
const double eps(1e-8);
const int maxn=10100;
const long long inf=-1u>>1;
typedef long long ll;
ll n;
struct BigInt{
	const static int mod=10000;
	const static int DLEN=4;
	int a[8],len;
	BigInt(){
		memset(a,0,sizeof(a));
		len=1;
	}
	BigInt(ll v){
		memset(a,0,sizeof(a));
		len=0;
		do{
			a[len++]=v%mod;
			v/=mod;
		}while(v);
	}
	BigInt operator +(const BigInt &b)const{
		BigInt res;
		res.len=max(len,b.len);
		for(int i=0;i<=res.len;i++) res.a[i]=0;
		for(int i=0;i<res.len;i++) {
			res.a[i] += ((i < len)?a[i]:0)+((i < b.len)?b.a[i]:0);
			res.a[i+1] += res.a[i]/mod;
			res.a[i] %= mod;
		}
		if(res.a[res.len]>0) res.len++;
		return res;
	}

	BigInt operator *(const BigInt &b)const{
		BigInt res;
		for(int i=0;i<len;i++){
			int up=0;
			for(int j=0;j<b.len;j++){
				int tmp=a[i]*b.a[j]+res.a[i+j]+up;//i位*j位,至少有i+j位
				res.a[i+j]=tmp%mod;
				up=tmp/mod;
			}
			if(up!=0){
				res.a[i+b.len]=up;
			}
		}
		res.len=len+b.len;
		while(res.a[res.len-1]==0 && res.len>1) res.len--;//调整长度
		return res;
	}
	void output(){
		printf("%d",a[len-1]);
		for(ll i=len-2;i>=0;i--) {
			printf("%04d",a[i]);//中间的显示前导0
		}
		printf("\n");
	}
};
int t,cas=1;

void init() {
	scanf("%I64d",&n);
}

void work() {
	BigInt ans=0;
	//ll ans1=0;
	int tmp;
	ll i;
	ll m=sqrt(n*1.0);
	if(m*10<=n) m=m*10;
	ll s=0;
	for(i=1;i<=m;i++){
		s+=n%i;
		tmp=i;
	}
	ans=ans+s;
	ll k=n/(tmp+1),l,r,cnt1,cnt2;
	for(l=tmp+1;k!=0;k--,l=r+1){
		r=n/k;
		cnt1=(n%l)/k;
		cnt2=cnt1+1;
		ans=ans+BigInt((n%r)*cnt2);
		//printf("%I64d %I64d\n",n%r,cnt2);
		if(cnt1&1) cnt2>>=1;
		else cnt1>>=1;
		ans=ans+BigInt(k*cnt1)*BigInt(cnt2);
	}
	printf("Case %d: ",cas++);
	ans.output();
	/*ll ans1=0;
	for(ll i=1;i<=n;i++){
		ans1+=n%i;
	}
	printf("Case %d: %I64d\n",cas++,ans1);*/
}

int main() {
	#ifndef ONLINE_JUDGE
	//freopen("in.txt","r",stdin);
	#endif
	scanf("%d",&t);
	while(t--){
		init();
		work();
	}

	return 0;
}


2014湖南邀请赛

标签:数学   大数   

原文地址:http://blog.csdn.net/lj94093/article/details/46116097

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!