ACM模板

本文介绍了快速傅立叶变换(FFT)在离散傅立叶变换(NTT)中的应用,以及Dinic算法在解决流网络最大流问题中的实例。通过这两个IT技术,文章展示了如何处理大规模数据的高效计算。
摘要由CSDN通过智能技术生成

NTT

ll t[2 * N], Len, A[2 * N], B[2 * N];
void Dft(ll *a, ll sig) {
    F(i, 0, Len - 1) {
        ll pos = 0;
        for (ll x = i, y = 0; y < cnt; y ++, x >>= 1) pos = (pos << 1) + (x & 1);
        t[pos] = a[i];
    }
    for (ll m = 2; m <= Len; m <<= 1) {
        ll hf = m / 2;
        F(i, 0, hf - 1) {
            ll w = ksm(3, ((i * sig * (mo - 1) / m) % (mo - 1) + (mo - 1)) % (mo - 1));
            for (ll j = i; j < Len; j += m) {
                ll u = t[j + hf] * w % mo;
                t[j + hf] = (t[j] - u) % mo;
                t[j] = (t[j] + u) % mo;
            }
        }
    }
    F(i, 0, Len - 1) a[i] = t[i];
}

for (Len = 1, cnt = 0; Len <= n + n ; Len <<= 1, cnt ++);
Dft(A, 1), Dft(B, 1);
F(i, 0, Len - 1) A[i] = A[i] * B[i] % mo;
Dft(A, - 1); ll NY = ksm(Len, mo - 2);
F(i, 0, Len - 1) A[i] = A[i] * NY % mo;

FFT

using namespace std;

const int N = 4e6 + 10;
const db pi = acos(- 1), wu = 1e-8;

int n, m, T, Len, cnt;
struct Z {
	db x, y;
	Z (db _x = 0, db _y = 0) { x = _x, y = _y; }
} a[N], b[N], t[N];

Z operator + (Z a, Z b) { return Z(a.x + b.x, a.y + b.y); }
Z operator - (Z a, Z b) { return Z(a.x - b.x, a.y - b.y); }
Z operator * (Z a, Z b) { return Z(a.x * b.x - a.y * b.y, a.x * b.y + a.y * b.x); }

void Dft(Z *a, int n, int sig) {
	F(i, 0, n - 1) {
		int pos = 0;
		for (int x = i, y = 0; y < cnt; y ++) pos = (pos << 1) + (x & 1), x = x >> 1;
		t[pos] = a[i];
	}
	for (int m = 2; m <= n; m <<= 1) {
		int half = m / 2;
		F(i, 0, half - 1) {
			Z w(cos(2 * i * pi / m), sin(2 * sig * i * pi / m));
			for (int j = i; j < n; j += m) {
				Z u = t[j + half] * w;
				t[j + half] = t[j] - u;
				t[j] = t[j] + u;
			}
		}
	}
	F(i, 0, n - 1) a[i] = t[i];
}

int main() {
	scanf("%d%d", &n, &m), T = n + m;
	F(i, 0, n) scanf("%lf", &a[i].x);
	F(i, 0, m) scanf("%lf", &b[i].x);

	for (Len = 1; Len <= n + m + 1; Len <<= 1, cnt ++); n = Len;

	Dft(a, n, 1), Dft(b, n, 1);
	F(i, 0, n - 1) a[i] = a[i] * b[i];
	Dft(a, n, - 1);

	F(i, 0, T) printf("%d ", int(a[i].x / Len + 0.5));
}

Dinic

const int N = 2e3 + 100;
const int M = 3e5 + 10;
int n, m, s, t, u, v, w;
int nx[M], to[M], len[M], las[N], cur[N], d[N],  co[N], tot = 1; // 注意tot=1

void link(int x, int y, int z) {
	to[++ tot] = y, nx[tot] = las[x], len[tot] = z, las[x] = tot;
	to[++ tot] = x, nx[tot] = las[y], len[tot] = 0, las[y] = tot;
}

int dg(int x, int sum) {
	if (x == t)
		return sum;
	int use = 0;
	for (int i = cur[x]; i; cur[x] = i = nx[i]) {
		cur[x] = i;
		if (len[i] > 0 && d[to[i]] + 1 == d[x]) {
			int c = dg(to[i], min(sum - use, len[i]));
			use += c, len[i] -= c, len[i ^ 1] += c;
			if (sum == use)
				return sum;
		}
	}
	cur[x] = las[x];
	if (!(--co[d[x]])) d[s] = n;
	++ co[++ d[x]];
	return use;
}

int main() {
	R(n), R(m), R(s), R(t);
	F(i, 1, m) R(u), R(v), R(w), link(u, v, w);

	long long ans = 0;
	co[0] = n;
	while (d[s] < n)
		ans += dg(s, 2147483647);
	W(ans);
}
  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值