[BZOJ3933][CQOI2015]多项式 && 高精度

首先你要发现n-m很小 可以直接得出系数的关系式

然后引用PoPoQQQ大牛的东西Orz 

用x替换式子中的x-t得到: 
nk=0ak(x+t)k=nk=0bkxk 
于是可以得到: 
bm=nk=mCkmkt km a k=nmi=0Cim+itiam+i 
其中ai=(2091234i mod 3388 +3181) mod 3389 

然后同样的 

出题人我*尼玛QAQ 

#include
#include
#include
#include
#include
#include
#define SF scanf
#define PF printf
using namespace std;
typedef long long LL;
const LL base = 1000000000LL;
const LL POW[]= { 1, 10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000, 1000000000 };
struct Hp {
	int Len;
	LL a[2010];
	LL operator [] (const int &t) const { return a[t]; }
	LL & operator [] (const int &t) { return a[t]; }
	Hp (LL x = 0) {
		memset(a, 0, sizeof(a)); Len = 0;
		while(x) { a[Len++] = x % base; x /= base; }
	}
	Hp fix() {
		while(Len && !a[Len-1]) Len--;
		return *this;
	}
	Hp operator = (LL &x) {
		memset(a, 0, sizeof(a)); Len = 0;
		while(x) { a[Len++] = x % base; x /= base; }
		return *this;
	}
	Hp operator + (const Hp &b) const {
		Hp c;
		c.Len = max(Len, b.Len) + 1;
		LL add = 0;
		for(int i = 0; i < c.Len; i++) {
			add += a[i] + b[i];
			c[i] = add % base;
			add /= base;
		}
		return c.fix();
	}
	int operator ^ (const Hp &b) const {
		LL ret = 0;
		for(int i = Len-1; i >= 0; i--) ret = ret * base + a[i] - b[i];
		return ret;
	}
	Hp operator - (const Hp &b) const {
		Hp c;
		c.Len = max(Len, b.Len);
		LL del = 0;
		for(int i = 0; i < c.Len; i++) {
			del += a[i] - b[i];
			c[i] = del; 
			del = 0;
			if(c[i] < 0) {
				LL tmp = (-c[i]-1) / base + 1;
				c[i] += tmp * base;
				del -= base;
			}
		}
		return c.fix();
	}
	Hp operator * (const Hp &b) const {
		Hp c;
		c.Len = Len + b.Len;
		for(int i = 0; i < Len; i++) {
			LL mul = 0;
			for(int j = 0; j <= b.Len; j++) {
				mul += a[i] * b[j] + c[i+j];
				c[i+j] = mul % base;
				mul /= base;
			}
		}
		return c.fix();
	}
	Hp operator / (const int &b) const {
		Hp c;
		c.Len = Len;
		LL over = 0;
		for(int i = Len-1; i >= 0; i--) {
			over = over * base + a[i];
			c[i] = over / b;
			over %= b;
		}
		return c.fix();
	}
	int operator % (const int &MOD) const {
		LL ret = 0;
		for(int i = Len-1; i >= 0; i--) ret = (ret * base + a[i]) % MOD;
		return ret;
	}
	Hp operator += (const  Hp &b) { return *this = *this + b; }
    Hp operator -= (const  Hp &b) { return *this = *this - b; }
    Hp operator *= (const  Hp &b) { return *this = *this * b; }
    Hp operator /= (const int &b) { return *this = *this / b; }
	bool operator <  (const Hp &b) const { 
        if(Len != b.Len) return Len < b.Len;
        for(int i = Len-1; i >= 0; i--) if(a[i] != b[i]) return a[i] < b[i];
        return false;
    }
    bool operator >  (const Hp &b) const {
        return b < *this;
    }
    bool operator <= (const Hp &b) const {
        return !(b < *this);
    }
    bool operator >= (const Hp &b) const {
        return !(*this < b);
    }
    bool operator != (const Hp &b) const {
        return *this < b || b < *this;
    }
    bool operator == (const Hp &b) const {
        return !(*this < b) && !(b < *this);
    }
} n, m;
char s1[3010], s2[3010];
int t;
int pow_mod(int x, int k) {
	int ret = 1;
	while(k) {
		if(k & 1) ret = ret * x % 3389;
		x = x * x % 3389;
		k >>= 1;
	}
	return ret;
}
void print(const Hp &A) {
	if(A.Len == 0) { putchar('0'); return ; }
	PF("%d", (int)A[A.Len-1]);
	for(int i = A.Len-2; i >= 0; i--) PF("%09d", (int)A[i]);
}
void st2i(char *s, Hp &x) {
	int len = strlen(s+1);
	for(int i = len; i; i--)
		x[(len-i)/9] += (s[i] - '0') * POW[(len-i) % 9];
	x.Len = len / 9 + 1;
}
int GetA(const Hp &x) {
	int tmp = x % 3388;
	return (209 * pow_mod(1234, tmp) + 3181) % 3389;
}
Hp C(1), T(1), ans;
int main() 
{
	int del = 0;
	SF("%s%d%s", s1+1, &t, s2+1);
	st2i(s1, n); st2i(s2, m);
	del = n^m;
	for(int i = 0; i <= del; i++) {
		if(i) {
			C *= m + i;
			C /= i;
			T *= t;
		}
		ans += C * T * GetA(m+i);
	}
	print(ans);
}


你可能感兴趣的:(BZOJ)