BZOJ1023 [SHOI2008]cactus仙人掌图
20150306

BZOJ1223 [HNOI2002]Kathy函数

laekov posted @ 2015年3月05日 18:36 in 未分类 with tags bzoj dp , 1083 阅读

比较神奇的数学题。首先你要知道这个函数的意思是把它的二进制flip。至于怎么来的我也是听说的。然后推一下发现的确是这么回事。

 

于是就变成数位dp了。然后我发现数位dp常常可以用奇奇怪怪的方法水过去。然后又发现数组从0开始标号也会造成麻烦。+1-1啥的最讨厌了。

 

于是这题就变成高精度练习题了。

 

#include <cstdio>
#include <cstring>
#include <algorithm>

using namespace std;

const int maxn = 409;

struct BigInt {
	int l, a[maxn], base;
	BigInt(int b = 10) {
		l = 0;
		base = b;
	}
	void push() {
		for (int i = 0; i < l - 1; ++ i) {
			a[i + 1] += a[i] / base;
			a[i] %= base;
		}
		for (; a[l - 1] >= base; ++ l) {
			a[l] = a[l - 1] / base;
			a[l - 1] %= base;
		}
	}
	void pull() {
		for (; l && !a[l - 1]; -- l);
	}
	void read() {
		static char g[maxn];
		base = 10;
		scanf("%s", g);
		l = strlen(g);
		for (int i = 0; i < l; ++ i)
			a[i] = g[l - i - 1] - 48;
		pull();
	}

	inline void setOne() {
		l = 1;
		a[0] = 1;
	}
	inline void setZero() {
		l = 0;
	}

	void assAdd(const BigInt& x) {
		for (int i = 0; i < l && i < x. l; ++ i)
			a[i] += x. a[i];
		for (int i = l; i < x. l; ++ i)
			a[i] = x. a[i];
		if (x. l > l)
			l = x. l;
		push();
	}
	void assDec() {
		-- a[0];
		for (int i = 0; a[i] < 0; ++ i) {
			a[i] += base;
			-- a[i + 1];
		}
		pull();
	}
	void assMul(int x) {
		for (int i = 0; i < l; ++ i)
			a[i] *= x;
		push();
	}
	int mod(int x) const {
		int s(0);
		for (int i = l - 1; i >= 0; -- i)
			s = (s * base + a[i]) % x;
		return s;
	}
	void assDiv(int x) {
		for (int i = l - 1; i >= 0; -- i) {
			if (i)
				a[i - 1] += a[i] % x * base;
			a[i] /= x;
		}
		pull();
	}
	int compareTo(const BigInt& x) const {
		if (l > x. l)
			return 1;
		else if (l < x. l)
			return -1;
		for (int i = l - 1; i >= 0; -- i)
			if (a[i] > x. a[i])
				return 1;
			else if (a[i] < x. a[i])
				return -1;
		return 0;
	}
	void ass(const BigInt& x) {
		static BigInt tmp;
		if (base == x. base) {
			l = x. l;
			memcpy(a, x. a, sizeof(a));
		}
		else {
			tmp. base = x. base;
			tmp. ass(x);
			for (l = 0; tmp. l; ++ l) {
				a[l] = tmp. mod(base);
				tmp. assDiv(base);
			}
		}
	}
	void print(char eon = 10) {
		for (int i = l - 1; i >= 0; -- i)
			putchar(a[i] + 48);
		if (!l)
			putchar(48);
		if (eon)
			putchar(eon);
	}
	void flip() {
		for (int i = 0; (i << 1) < l; ++ i)
			swap(a[i], a[l - i - 1]);
		pull();
	}
};

BigInt tmp, m, bm(2), br(2), ans, p2[maxn], ONE;

bool checkFlip(const BigInt& a) {
	int q(a. l >> 1), p(a. l - q - 1);
	for (int i = 0; p - i >= 0; ++ i)
		if (a. a[p - i] > a. a[q + i])
			return 1;
		else if (a. a[p - i] < a. a[q + i])
			return 0;
	return 1;
}

int main() {
#ifndef ONLINE_JUDGE
	freopen("in.txt", "r", stdin);
#endif

	ONE. setOne();
	tmp. read();
	m. ass(tmp);
	bm. ass(tmp);
	int l((bm. l + 1) >> 1);
	p2[0]. setOne();
	for (int i = 1; i <= l; ++ i) {
		p2[i]. ass(p2[i - 1]);
		p2[i]. assMul(2);
	}
	for (int i = 1; i < bm. l; ++ i)
		ans. assAdd(p2[((i + 1) >> 1) - 1]);
	for (int i = bm. l - 2; i > bm. l - l - 1; -- i)
		if (bm. a[i])
			ans. assAdd(p2[i - (bm. l >> 1)]);
	if (checkFlip(bm))
		ans. assAdd(ONE);
	ans. print();
}

登录 *


loading captcha image...
(输入验证码)
or Ctrl+Enter