zoukankan      html  css  js  c++  java
  • [HNOI2004]高精度开根

    题目:洛谷P2293、BZOJ1213。

    题目大意:给你$n,k(nleq 10^{10000},kleq 50)$,求$lfloor sqrt[k]{n} floor$。

    解题思路:高精度+二分+快速幂。

    我压了九位。

    这题真的卡的我丧心病狂啊!!开始无脑高精度,后来T的不知道哪去了。

    首先高精度乘法中除法取模运算特别慢,要放在乘完后再处理。

    还有最重要的优化:如果当前的答案的位数乘k减k+1大于n的位数,则不需要进行乘法,因为答案一定失败。

    然后尽量减少传值,努力卡常即可。

    可怜我压九位居然只输出八位,找了一小时错!

    C++ Code:

    %:pragma GCC optimize(2)
    #include<cstring>
    #include<cstdio>
    using namespace std;
    char READ[10200];
    int k;
    typedef unsigned long long ll;
    struct BigInteger{
    	typedef unsigned long long ll;
    	static const ll base=1000000000;
    	ll v[1992];
    	int size;
    	BigInteger():size(0){
    		memset(v,0,sizeof v);
    	}
    	void print(){
    		printf("%llu",v[size]);
    		for(int i=size-1;i>0;--i)
    		printf("%09llu",v[i]);
    		putchar('
    ');
    	}
    	void ch(const BigInteger& b){
    		BigInteger c;
    		for(int i=1;i<=size;++i)
    		for(int j=1;j<=b.size;++j)
    		c.v[i+j-1]+=(v[i]*b.v[j]);
    		c.size=size+b.size+2;
    		for(int i=1;i<=c.size;++i)
    		c.v[i+1]+=c.v[i]/base,c.v[i]%=base;
    		while(!c.v[c.size])--c.size;
    		*this=c;
    	}
    	BigInteger operator +(const BigInteger& b)const{
    		BigInteger c;
    		c.size=size;
    		if(size<b.size)c.size=b.size;
    		for(int i=1;i<=c.size;++i){
    			c.v[i]+=v[i]+b.v[i];
    			c.v[i+1]=c.v[i]/base;
    			c.v[i]%=base;
    		}
    		if(c.v[c.size+1])++c.size;
    		return c;
    	}
    	BigInteger inc(){
    		BigInteger c=*this;
    		c.v[1]++;
    		int now=1;
    		while(c.v[now]>=base){
    			c.v[now+1]++;
    			c.v[now++]-=base;
    		}
    		if(c.v[c.size+1])++c.size;
    		return c;
    	}
    	BigInteger dec(){
    		BigInteger c=*this;
    		c.v[1]--;
    		int now=1;
    		while(c.v[now]<0){
    			c.v[now+1]--;
    			c.v[now++]+=base;
    		}
    		if(!c.v[c.size])--c.size;
    		return c;
    	}
    	bool operator <=(const BigInteger& b)const{
    		if(size!=b.size)return size<b.size;
    		for(int i=size;i>0;--i)
    		if(v[i]!=b.v[i])return v[i]<b.v[i];
    		return true;
    	}
    }a,l,r,mid,ans;
    void read(){
    	scanf("%s",READ);
    	int len=strlen(READ);
    	a.size=0;
    	ll now=0,wid=1;
    	for(int i=len-1;i+1;--i){
    		now+=(READ[i]^'0')*wid;
    		wid*=10;
    		if(wid==1000000000){
    			wid=1;
    			a.v[++a.size]=now;
    			now=0;
    		}
    	}
    	if(now)a.v[++a.size]=now;
    }
    void average(){
    	for(int i=mid.size;i;--i){
    		mid.v[i-1]+=(mid.v[i]&1ll)*mid.base;
    		mid.v[i]>>=1;
    	}
    	mid.v[0]=0;
    	while(!mid.v[mid.size])--mid.size;
    }
    bool power(BigInteger a,int k){
    	BigInteger p;
    	p.size=p.v[1]=1;
    	while(k){
    		if(k&1)p.ch(a);
    		if(p.size>::a.size)return false;
    		a.ch(a);
    		k>>=1;
    	}
    	return p<=::a;
    }
    int main(){
    	scanf("%d",&k);
    	read();
    	if(k==1||a.size==0){
    		a.print();
    		return 0;
    	}
    	l.size=l.v[1]=1;
    	r=a;
    	while(l<=r){
    		mid=l+r;
    		average();
    		if(mid.size*k-k+1<=a.size&&power(mid,k))
    		l=(ans=mid).inc();else
    		r=mid.dec();
    	}
    	ans.print();
    	return 0;
    }
    
  • 相关阅读:
    Codeforces Round #388(div 2)
    Codeforces Round #387(div 2)
    Codeforces Round #386(div 2)
    Codeforces Round #385(div 2)
    Codeforces Round #384(div 2)
    Wannafly Union Goodbye 2016
    写在2016的最后一天——给未来的自己
    2016HDU校赛
    2016BUAA校赛决赛
    codevs 1344 模拟退火
  • 原文地址:https://www.cnblogs.com/Mrsrz/p/7678775.html
Copyright © 2011-2022 走看看