F题
对于第个区间
,将区间
染上第
种颜色。
对于能够创建的区间的左右端点,这两个端点混合之后的颜色一定完全相同。
考虑对每一个端点的染色方案进行哈希。
因为,可以使用随机异或哈希。对于所有需要染色的区间,用线段树维护一下即可。
时间复杂度:
#define _USE_MATH_DEFINES
#include <bits/stdc++.h>
#define int long long
#define Z 1LL << 10
using namespace std;
using i64 = long long;
using i128 = __int128;
using ld = long double;
using u64 = unsigned long long;
typedef pair<int, int> pii;
const int N = 2e5 + 5;
const int M = 4e6 + 5;
const int mod = 3;
const i64 inf = 0x3f3f3f3f3f3f3f3f;
std::mt19937 rnd(time(0));
constexpr long double pi = static_cast<long double>(M_PI);
int dx[4] = { -1, 0, 1, 0}, dy[4] = {0, 1, 0, -1};
int n, m;
int a[N];
struct segmenttree
{
struct node
{
int l, r, maxx, tag;
};
vector<node>tree;
segmenttree(): tree(1) {}
segmenttree(int n): tree(n * 4 + 1) {}
void pushup(int u)
{
auto &root = tree[u], &left = tree[u << 1], &right = tree[u << 1 | 1];
root.maxx = max(left.maxx, right.maxx);
}
void pushdown(int u)
{
auto &root = tree[u], &left = tree[u << 1], &right = tree[u << 1 | 1];
if (root.tag != 0)
{
left.tag ^= root.tag;
right.tag ^= root.tag;
left.maxx ^= root.tag;
right.maxx ^= root.tag;
root.tag = 0;
}
}
void build(int u, int l, int r)
{
auto &root = tree[u];
root = {l, r};
if (l == r)
{
root.maxx = 0;
}
else
{
int mid = l + r >> 1;
build(u << 1, l, mid);
build(u << 1 | 1, mid + 1, r);
pushup(u);
}
}
void modify(int u, int l, int r, int val)
{
auto &root = tree[u];
if (root.l >= l && root.r <= r)
{
root.maxx ^= val;
root.tag ^= val;
return;
}
pushdown(u);
int mid = root.l + root.r >> 1;
if (l <= mid) modify(u << 1, l, r, val);
if (r > mid) modify(u << 1 | 1, l, r, val);
pushup(u);
}
int query(int u, int l, int r)
{
auto &root = tree[u];
if (root.l >= l && root.r <= r)
{
return root.maxx;
}
pushdown(u);
int mid = root.l + root.r >> 1;
int res = 0;
if (l <= mid) res = query(u << 1, l, r);
if (r > mid) res = max(res, query(u << 1 | 1, l, r));
return res;
}
};
int calc(int x)
{
return x * (x + 1) / 2;
}
void solve()
{
cin >> n >> m;
segmenttree smt(m);
smt.build(1, 1, m);
for (int i = 1, l, r; i <= n; i++)
{
cin >> l >> r;
if (l + 1 <= r - 1)
smt.modify(1, l + 1, r - 1, rnd());
a[l]++, a[r]++;
}
map<int, int>mp;
for (int i = 1; i <= m; i++)
{
if (a[i]) continue;
mp[smt.query(1, i, i)]++;
}
int ans = 0;
for (auto mpp : mp)
{
int cnt = mpp.second;
ans += calc(cnt);
}
cout << ans << endl;
}
signed main()
{
ios::sync_with_stdio(false);
cin.tie(0), cout.tie(0);
int test = 1;
// cin >> test;
for (int i = 1; i <= test; i++)
{
solve();
}
return 0;
}

京公网安备 11010502036488号