求助下午牛客 C 题
  • 板块学术版
  • 楼主junxis
  • 当前回复0
  • 已保存回复0
  • 发布时间2023/1/18 19:12
  • 上次更新2023/10/24 03:41:47
查看原帖
求助下午牛客 C 题
551375
junxis楼主2023/1/18 19:12

过不去啊,求调。

思路就是先差分,统计出每个点被区间的覆盖次数,然后枚举 ii,将答案加上 cov(i)cov(ni)cov(i)*cov(n-i),然后再枚举区间,减去 i,nii,n-i 均落在区间内的情况。

#include<bits/stdc++.h>
using namespace std;
#define rep(i,a,n) for (int i=a;i<n;i++)
#define per(i,a,n) for (int i=n-1;i>=a;i--)
#define pb push_back
#define eb emplace_back
#define mp make_pair
#define all(x) (x).begin(), (x).end()
#define fi first
#define se second
#define SZ(x) ((int)(x).size())
typedef vector<int> VI;
typedef basic_string<int> BI;
typedef long long ll;
typedef pair<int, int> PII;
typedef double db;
mt19937 mrand(random_device{}());
const ll mod=998244353;
int rnd(int x) { return mrand() % x; }
ll powmod(ll a,ll b) {ll res=1;a%=mod; assert(b>=0); for (;b;b>>=1) { if (b&1) res=res*a%mod; a=a*a%mod;} return res;}
ll gcd(ll a, ll b) {return b?gcd(b,a%b):a;}
// head

const int N = 401000;
int n, m, d[N], l[N], r[N];

int main() {
	scanf("%d%d", &n, &m);
	int V = 0;
	rep(i,1,m+1) {
		scanf("%d%d", &l[i], &r[i]);
		d[r[i] + 1] -= 1;
		d[l[i]] += 1;
		V = max(V, r[i]);
	}
	rep(i,1,V+1) d[i] += d[i - 1];
	ll ans = 0;
	rep(i,1,V+1) {
		ans = (ans + 1ll * d[i] * d[n - i] % mod) % mod;
	}
	rep(i,1,m+1) {
		int l2 = n - r[i], r2 = n - l[i];
		l2 = max(l2, l[i]), r2 = min(r2, r[i]);
		ans = (ans - max(0, (r2 - l2 + 1)) % mod + mod) % mod;
        if (ans < 0) ans += mod;
	}
	if (ans < 0) ans += mod;
	printf("%lld\n", ans);
}
2023/1/18 19:12
加载中...