[Nowcoder212D] banned directory _ probability expectations

Banned directory

Subject to the effect : Puritan need to periodically clear the memory Index, before this need to be among the one hundred and three thousand banned taken out ...... Unfortunately, once banned left the Index is very fragile, specifically, each has a forbidden book magic value a I , the content of which is described in B I , after taking out the present n- different banned form a permutation, if a banned for i, which is not weaker than the left one is present it banned magic value j, i will be banned because of the influence banned j disappear. Banned for all possible seek arrangement described can be retained and the content of the number of species. Since the answer may be large, the output only after the results of the film can take 998,244,353.

Data range :. 1. 5 ≤ X ≤ n-10 . 5 , 1 ≦ A I , B I ≤ 10 . 8


Problem solution :

Well this question

The first track count problem turn into a probability expectation of.

Mostly, this problem can not count the number, think of it too much to hold back, we turn it into the desired probability.

Suppose $ A $ current value is not less than the A $ $ $ book CNT has $ present, then the probability of surviving the book is $ \ frac {1} {cnt} $.

So for each book, work out all probability not live down, and finally multiplied by the factorial enough.

Note that, if there have been two books are identical, then we can only count as one in which the book will be in the back of the front kill anyway.

Code :

#include <bits/stdc++.h>

#define N 500010 

using namespace std;

typedef long long ll;

const int mod = 998244353 ; 

map<int, int> MP;

struct Node {
	int x, y;
}a[N], b[N];

inline bool cmp(const Node &a, const Node &b) {
	return a.x == b.x ? a.y < b.y : a.x < b.x;
}
inline bool operator == (const Node &a, const Node &b) {
	return a.x == b.x && a.y == b.y;
}

char *p1, *p2, buf[100000];

#define nc() (p1 == p2 && (p2 = (p1 = buf) + fread(buf, 1, 100000, stdin), p1 == p2) ? EOF : *p1 ++ )

int rd() {
	int x = 0;
	char c = nc();
	while (c < 48) {
		c = nc();
	}
	while (c > 47) {
		x = (((x << 2) + x) << 1) + (c ^ 48), c = nc();
	}
	return x;
}

int qpow(int x, int y) {
	int ans = 1;
	while (y) {
		if (y & 1) {
			ans = (ll)ans * x % mod;
		}
		y >>= 1;
		x = (ll)x * x % mod;
	}
	return ans;
}

int c[N << 1], cnt, re[N << 1];

int main() {
	int n = rd();
	int sum = 1;
	for (int i = 1; i <= n; i ++ ) {
		sum = (ll)sum * i % mod;
	}
	for (int i = 1; i <= n; i ++ ) {
		a[i].x = rd(), a[i].y = rd();
		c[ ++ cnt] = a[i].x, c[ ++ cnt] = a[i].y;
	}
	int tot = 0;
	sort(c + 1, c + cnt + 1);
	c[0] = c[1] - 1;
	for (int i = 1; i <= cnt; i ++ ) {
		if (c[i] != c[i - 1]) {
			MP[c[i]] = ++tot;
		}
	}
	for (int i = 1; i <= n; i ++ ) {
		a[i].x = MP[a[i].x], a[i].y = MP[a[i].y];
	}

	sort(a + 1, a + n + 1, cmp);
	int pre = 0;
	for (int i = 1; i <= tot; i ++ ) {
		re[i] = 1;
	}
	for (int i = 1; i <= n; i ++ ) {
		int dic = i;
		while (dic < n && a[dic] == a[dic + 1]) {
			dic ++ ;
		}
		if (a[i].x != a[pre].x) {
			pre = i;
		}
		int mdl = n - pre + 1;
		re[a[dic].y] = (ll)re[a[dic].y] * (mdl - (dic - i + 1)) % mod * qpow(mdl, mod - 2) % mod;
		i = dic;
	}
	int ans = 0;
	for (int i = 1; i <= tot; i ++ ) {
		ans = (ans + (1 - re[i] + mod) % mod) % mod;
	}
	cout << (ll)ans * sum % mod << endl ;
	return 0;
}

Summary : Good question ah, this title feels meaningful. If the number is met a number of questions absolutely no idea (timely modulus tempting), we can consider the probability of converting to expect to do.

Guess you like

Origin www.cnblogs.com/ShuraK/p/11256762.html