2019ICPC上海网络赛

C Triple

在这里插入图片描述

#include<iostream>
#include<algorithm>
#include<cmath>
using namespace std;

struct cp {
	double x, y;
	cp operator+(cp a) { return { x + a.x, y + a.y }; }
	cp operator-(cp a) { return { x - a.x, y - a.y }; }
	cp operator*(cp a) { return { x*a.x - y * a.y,x*a.y + y * a.x }; }
};

const int maxn = 270000;
int rev[maxn]; cp w[maxn];

void fft(cp x[], int len, int on) {
	for (int i = 0; i < len; i++)rev[i] = (rev[i >> 1] >> 1) + (i & 1)*(len >> 1);
	for (int i = 0; i < len; i++)if (i < rev[i])swap(x[i], x[rev[i]]);
	for (int i = 2; i <= len; i <<= 1) {
		int wn = len / i, d = i / 2;
		for (int j = 0; j < len; j += i) {
			int wk = 0;
			for (int k = j; k < j + d; k++) {
				cp a = x[k], b = w[wk] * x[k + d];
				x[k] = a + b, x[k + d] = a - b;
				wk += wn;
			}
		}
	}
	if (on == -1) {
		reverse(x + 1, x + len);
		for (int i = 0; i < len; i++)x[i].x /= len;
	}
}

#define ll long long
const int lim = 1e5 + 10;

ll n;
ll a[maxn], b[maxn], c[maxn];
cp aa[maxn], bb[maxn], cc[maxn];
cp bc[maxn], ac[maxn], ab[maxn];
ll sbc[maxn], sac[maxn], sab[maxn];


int main() {
	ios::sync_with_stdio(0); cin.tie(0);
	int t; cin >> t;
	for (int i = 1; i <= t; i++) {
		cin >> n;
		for (int i = 1; i <= n; i++)cin >> a[i];
		for (int i = 1; i <= n; i++)cin >> b[i];
		for (int i = 1; i <= n; i++)cin >> c[i];

		int len = 1 << 18;
		const double pi = acos(-1);
		for (int i = 0; i < len / 2; i++) {
			double a = 2 * pi*i / len;
			double c = cos(a), s = sin(a);
			w[i] = { c,s }; w[i + len / 2] = { -c,-s };

		}

		ll ans = n * n*n;

		if (n <= 1000) {
			for (int i = 0; i < lim; i++) {
				sab[i] = sbc[i] = sac[i] = 0;
			}

			for (int i = 1; i <= n; i++) {
				for (int j = 1; j <= n; j++) {
					if (a[i] + b[j] < lim)sab[a[i] + b[j]]++;
					if (b[i] + c[j] < lim)sbc[b[i] + c[j]]++;
					if (a[i] + c[j] < lim)sac[a[i] + c[j]]++;
				}
			}

			for (int i = 1; i < lim; i++) {
				sab[i] += sab[i - 1];
				sac[i] += sac[i - 1];
				sbc[i] += sbc[i - 1];
			}

			for (int i = 1; i <= n; i++) {
				ans -= sab[c[i] - 1];
				ans -= sbc[a[i] - 1];
				ans -= sac[b[i] - 1];
			}

		}
		else {
			for (int i = 0; i < len; i++) {
				sab[i] = sbc[i] = sac[i] = 0;
				aa[i].x = aa[i].y = 0;
				bb[i].x = bb[i].y = 0;
				cc[i].x = cc[i].y = 0;
				ab[i].x = ab[i].y = 0;
				bc[i].x = bc[i].y = 0;
				ac[i].x = ac[i].y = 0;
			}

			for (int i = 1; i <= n; i++) {
				aa[a[i]].x++;
				bb[b[i]].x++;
				cc[c[i]].x++;
			}

			//for (int i = 0; i < 8; i++)cout << aa[i].x << " " << bb[i].x << " " << cc[i].x << endl;

			fft(aa, len, 1);
			fft(bb, len, 1);
			fft(cc, len, 1);

			for (int i = 0; i < len; i++) {
				ab[i] = aa[i] * bb[i];
				bc[i] = bb[i] * cc[i];
				ac[i] = aa[i] * cc[i];
			}

			fft(ab, len, -1);
			fft(bc, len, -1);
			fft(ac, len, -1);

			//for (int i = 0; i < 8; i++)cout << ab[i].x << " " << bc[i].x << " " << ac[i].x << endl;

			for (int i = 0; i < lim; i++) {
				sab[i] = (ll)(ab[i].x + 0.5);
				sbc[i] = (ll)(bc[i].x + 0.5);
				sac[i] = (ll)(ac[i].x + 0.5);
			}

			for (int i = 1; i < lim; i++) {
				sab[i] += sab[i - 1];
				sbc[i] += sbc[i - 1];
				sac[i] += sac[i - 1];
			}

			for (int i = 1; i <= n; i++) {
				ans -= sab[c[i] - 1];
				ans -= sbc[a[i] - 1];
				ans -= sac[b[i] - 1];
			}

		}

		cout << "Case #" << i << ": " << ans << endl;
	}
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值