见证者为见证而来,铭记者因铭记而生|

园龄:粉丝:关注:

[CF2353D] Refined Product Optimality 题解

首先让我们输出的是不操作的值。不定序,一看就很贪心。经过分类分类分类可证,a,b 都是升序(降序)的时候是最优的。
再看加操作的。相当于要维护这两个升序序列。我们发现,每次操作影响的值很少,最多两个值。在一个连续段中,修改的值相当于和末尾值交换,再加一。

唐点:
找这个末尾没必要维护一堆下标然后写挂,用个二分足矣。反正用了排序,都是带 log 的。

#include <bits/stdc++.h>
#define inf 0x3f3f3f3f
#define Linf 0x3f3f3f3f3f3f3f3f
#define pii pair<int, int>
#define int long long 
#define all(v) v.begin(), v.end()
using namespace std;

//#define filename "xxx" 
#define FileOperations() freopen(filename".in", "r", stdin), freopen(filename".out", "w", stdout)


namespace Traveller {
	const int N = 4e5+2, mod = 998244353;
	void mul(int &a, int b, int p = mod) { a = (a * b % p + p) % p; }
	int qpow(int a, int b, int p = mod) {
		int res = 1;
		a %= p;
		while(b) {
			if(b & 1) mul(res, a, p);
			b >>= 1;
			mul(a, a, p);
		}
		return res;
	} 
	int inv(int a) { return qpow(a, mod-2); }
	
	int n, q;
	pii a[N], b[N];
	int c[N], d[N];
	int rev1[N], rev2[N];
	
	int ans;
	void work(pii *a, pii *b, int *c, int *rev, int x) {
		x = c[x];
		int y = upper_bound(a+1, a+n+1, pii(a[x].first, inf)) - a - 1;
		int p = rev[x], q = rev[y];
		
		//swap
		c[p] = y, c[q] = x;
		rev[x] = q, rev[y] = p;
		swap(x, y);
		
		mul(ans, inv(min(a[x].first, b[x].first)));
		mul(ans, min(++a[x].first, b[x].first));
	}
	
	void main() {
		cin >> n >> q;
		for(int i = 1, x; i <= n; ++i) {
			scanf("%lld", &x);
			a[i] = pii(x, i);
		}
		for(int i = 1, x; i <= n; ++i) {
			scanf("%lld", &x);
			b[i] = pii(x, i);
		}
		sort(a+1, a+n+1);
		sort(b+1, b+n+1);
		for(int i = 1; i <= n; ++i) c[a[i].second] = i, rev1[i] = a[i].second;
		for(int i = 1; i <= n; ++i) d[b[i].second] = i, rev2[i] = b[i].second;
		
		ans = 1;
		for(int i = 1; i <= n; ++i) mul(ans, min(a[i].first, b[i].first));
		printf("%lld ", ans);
		for(int i = 1, opt, x; i <= q; ++i) {
			scanf("%lld%lld", &opt, &x);
			if(opt == 1) work(a, b, c, rev1, x);
			else work(b, a, d, rev2, x);
			printf("%lld ", ans);
		}
		puts("");
	}
}

signed main() {
	#ifdef filename
		FileOperations();
	#endif
	
	int _;
	cin >> _;
	while(_--) Traveller::main();
	return 0;
}


posted @   wfc284  阅读(21)  评论(0编辑  收藏  举报
点击右上角即可分享
微信分享提示
评论
收藏
关注
推荐
深色
回顶
收起