您的位置:首页 > 其它

BigInteger应用于概率DP ZOJ 3380 WA TLE

2015-03-12 10:00 399 查看
不用高精度必然WA,把BigInteger移植到cpp往往TLE

#include<cctype>
#include<cmath>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
#include<string>
#include<queue>
#include<stack>
#include<set>
#include<map>
#define CLEAR(a) memset((a),0,sizeof((a)))

using namespace std;

typedef long long LL;
const int MAXN=100;
struct BigInteger
{
int len, s[MAXN];
BigInteger ()
{
memset(s, 0, sizeof(s));
len = 1;
}
BigInteger (int num) { *this = num; }
BigInteger (const char *num) { *this = num; }
BigInteger operator = (const int num)
{
char s[MAXN];
sprintf(s, "%d", num);
*this = s;
return *this;
}
BigInteger operator = (const char *num)
{
for(int i = 0; num[i] == '0'; num++) ;
len = strlen(num);
for(int i = 0; i < len; i++) s[i] = num[len-i-1] - '0';
return *this;
}
BigInteger operator + (const BigInteger &b) const //+
{
BigInteger c;
c.len = 0;
for(int i = 0, g = 0; g || i < max(len, b.len); i++)
{
int x = g;
if(i < len) x += s[i];
if(i < b.len) x += b.s[i];
c.s[c.len++] = x % 10;
g = x / 10;
}
return c;
}
BigInteger operator += (const BigInteger &b)
{
*this = *this + b;
return *this;
}
void clean()
{
while(len > 1 && !s[len-1]) len--;
}
bool odd()
{
return s[0]&1;
}
BigInteger operator * (const BigInteger &b) //*
{
BigInteger c;
c.len = len + b.len;
for(int i = 0; i < len; i++)
{
for(int j = 0; j < b.len; j++)
{
c.s[i+j] += s[i] * b.s[j];
}
}
for(int i = 0; i < c.len; i++)
{
c.s[i+1] += c.s[i]/10;
c.s[i] %= 10;
}
c.clean();
return c;
}
BigInteger operator *= (const BigInteger &b)
{
*this = *this * b;
return *this;
}
BigInteger operator - (const BigInteger &b)
{
BigInteger c;
c.len = 0;
for(int i = 0, g = 0; i < len; i++)
{
int x = s[i] - g;
if(i < b.len) x -= b.s[i];
if(x >= 0) g = 0;
else
{
g = 1;
x += 10;
}
c.s[c.len++] = x;
}
c.clean();
return c;
}
BigInteger operator -= (const BigInteger &b)
{
*this = *this - b;
return *this;
}
BigInteger operator / (const BigInteger &b)
{
BigInteger c, f = 0;
for(int i = len-1; i >= 0; i--)
{
f = f*10;
f.s[0] = s[i];
while(f >= b)
{
f -= b;
c.s[i]++;
}
}
c.len = len;
c.clean();
return c;
}
BigInteger operator /= (const BigInteger &b)
{
*this  = *this / b;
return *this;
}
BigInteger operator % (const BigInteger &b)
{
BigInteger r = *this / b;
r = *this - r*b;
return r;
}
BigInteger operator %= (const BigInteger &b)
{
*this = *this % b;
return *this;
}
BigInteger operator >> (int n)
{
BigInteger r=*this;
for(int i=1;i<=n;i++) r/=2;
return r;
}
bool operator < (const BigInteger &b)
{
if(len != b.len) return len < b.len;
for(int i = len-1; i >= 0; i--)
{
if(s[i] != b.s[i]) return s[i] < b.s[i];
}
return false;
}
bool operator > (const BigInteger &b)
{
if(len != b.len) return len > b.len;
for(int i = len-1; i >= 0; i--)
{
if(s[i] != b.s[i]) return s[i] > b.s[i];
}
return false;
}
bool operator == (const BigInteger &b)
{
return !(*this > b) && !(*this < b);
}
bool operator != (const BigInteger &b)
{
return !(*this == b);
}
bool operator <= (const BigInteger &b)
{
return *this < b || *this == b;
}
bool operator >= (const BigInteger &b)
{
return *this > b || *this == b;
}
string str() const
{
string res = "";
for(int i = 0; i < len; i++) res = char(s[i]+'0') + res;
return res;
}
};

istream& operator >> (istream &in, BigInteger &x)
{
string s;
in >> s;
x = s.c_str();
return in;
}

ostream& operator << (ostream &out, const BigInteger &x)
{
out << x.str();
return out;
}

BigInteger gcd(BigInteger n,BigInteger r)
{
return (n%r>0)?gcd(r,n%r):r;
}

LL gcd(LL n,LL r)
{
return (n%r>0)?gcd(r,n%r):r;
}

BigInteger sqr(BigInteger n)
{
return n*n;
}

LL sqr(LL n)
{
return n*n;
}

BigInteger pow(BigInteger n,BigInteger m)
{
if (m==1) return n;
else if (m.odd()) return pow(n,(m+1)>>1)*pow(n,(m-1)>>1);
else return sqr(pow(n,m>>1));
}

BigInteger pow(int n,int m)
{
return pow(BigInteger(n),BigInteger(m));
}

LL pow(LL n,LL m)
{
if (m==1) return n;
else if (m&1) return sqr(pow(n,(m+1)>>1))*n;
else return sqr(pow(n,m>>1));
}

const double pi = acos(-1.0);
const int maxn=100;
const int inf=99999999;
const float eps=1e-3;

BigInteger dp[maxn][maxn],g[maxn][maxn];
//LL dp[maxn][maxn],g[maxn][maxn];

void cnt()
{
for(int i=0;i<maxn;i++)
{
g[i][0]=g[i][i]=1;
if (i>1)
for(int j=1;j<i;j++)
g[i][j]=g[i-1][j]+g[i-1][j-1];
}
//printf("%BigIntegerd\n",g[maxn][maxn]);
//cout<<g[maxn-1][(maxn-1)/2]<<endl;
}

int main()
{
cnt();
int n,m,l;
while(~scanf("%d%d%d",&m,&n,&l))
{
if (m<l)
{
puts("mukyu~");break;
}
BigInteger tot=pow(n,m),fac=0;
//LL tot=pow(n,m),fac=0;
if(l>m/2){
for(int i=l;i<=m;i++){
fac+=g[m][i]*pow(n-1,m-i);
}
fac*=n;
}
else {
CLEAR(dp);
dp[0][0]=1;
for(int i=1;i<=n;i++){
for(int j=0;j<=m;j++){
for(int k=0;k<=j && k<l;k++){
dp[i][j]+=dp[i-1][j-k]*g[m-j+k][k];
}
}
}
fac=tot-dp
[m];
}
BigInteger tmp=gcd(fac,tot);
//LL tmp=gcd(fac,tot);
fac/=tmp;
tot/=tmp;
cout<<fac<<'/'<<tot<<endl;
//printf("%lld/%lld\n",fac,tot);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: