【51Nod 1501】【算法马拉松 19D】石头剪刀布威力加强版

http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1501
dp求出环状不连续的前缀和,剩下东西都可以算出来,比较繁琐。
时间复杂度\(O(n+m)\)

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;

typedef long long ll;
const int N = 500003;

int a[N], b[N], n, m, f[N][3], id[N];
ll k, win = 0, los = 0;

int gcd(int a, int b) {return b == 0 ? a : gcd(b, a % b);}

int main() {
	scanf("%d%d%lld", &n, &m, &k);
	for (int i = 0; i < n; ++i)
		scanf("%d", a + i);
	for (int i = 0; i < m; ++i)
		scanf("%d", b + i);
	int ret = 0;
	if (n > m) {
		swap(a, b);
		swap(n, m);
		ret ^= 1;
	}
	
	int g = gcd(n, m), delta = n, tmp, tot = 0;
	for (int i = 0; i < g; ++i)
		for (int j = 0; j < 3; ++j)
			f[i][j] = (b[i] == j), id[i] = ++tot;
	
	tmp = 0;
	int tms = m / g;
	for (int i = 1; i < tms; ++i) {
		tmp = (tmp + delta) % m;
		for (int j = tmp; j < tmp + g; id[j] = ++tot, ++j)
			for (int k = 0; k < 3; ++k)
				f[j][k] = f[(j - delta + m) % m][k] + (b[j] == k);
	}
	
	int pos, beat, lose, end;
	for (int i = 0; i < n; ++i) {
		pos = tmp + i % g;
		beat = (a[i] + 1) % 3;
		lose = (a[i] - 1 + 3) % 3;
		win += f[pos][beat];
		los += f[pos][lose];
	}
	end = tmp;
	
	ll lun = 1ll * n * m / g;
	win = win * (k / lun);
	los = los * (k / lun);
	k = k % lun;
	
	for (int i = 0; i < n; ++i) {
		if (i + 1 <= k)
			tms = (k - i - 1) / n + 1;
		else
			continue;
		pos = i; tmp = (int) ((1ll * delta * (tms - 1) % m + pos) % m);
		beat = (a[i] + 1) % 3;
		lose = (a[i] - 1 + 3) % 3;
		if ((tmp + delta) % m == pos) {
			win += f[end + i % g][beat];
			los += f[end + i % g][lose];
		} else if (pos < g) {
			win += f[tmp][beat];
			los += f[tmp][lose];
		} else
			if (id[pos] <= id[tmp]) {
				win += f[tmp][beat] - f[(pos - delta + m) % m][beat];
				los += f[tmp][lose] - f[(pos - delta + m) % m][lose];
			} else {
				win += f[tmp][beat] + f[end + i % g][beat] - f[(pos - delta + m) % m][beat];
				los += f[tmp][lose] + f[end + i % g][lose] - f[(pos - delta + m) % m][lose];
			}
	}
	
	if (ret) swap(win, los);
	printf("%lld %lld\n", win, los);
	return 0;
}
posted @ 2016-11-07 19:22  abclzr  阅读(448)  评论(0编辑  收藏  举报