RT,我的想法是用线段树分治,把询问离线下来,递归到每个节点时,进入房间就flag=1,离开就flag=0,进入的时候顺便检查一下,询问包含它的那些人,另外一个人在不在房间。感觉这样的做法应该是O(nlognlogn)的,但是一直在TLE,有人能证明这个复杂度是假的嘛
#include <bits/extc++.h>
#include <bits/stdc++.h>
using namespace std;
using namespace __gnu_pbds;
using namespace __gnu_cxx;
const int maxn = 1e6 + 5;
vector<pair<int, int>> qq[maxn];//编号为i,first为b的编号,second为询问编号
bitset<maxn> flag;
long long ans[maxn];
class A
{
public:
int t, p;
} a[maxn];
long long rd[maxn];
vector<int> d;
int mp[maxn];
class SegmentTree
{
public:
vector<int> a[4 * maxn];
void updata1(int x, int y, int p, int l, int r, int rt)
{
if (x <= l && y >= r)
{
a[rt].push_back(p);
return;
}
int mid = (l + r) / 2;
if (x <= mid)
updata1(x, y, p, l, mid, rt * 2);
if (y > mid)
updata1(x, y, p, mid + 1, r, rt * 2 + 1);
}
void query(int l, int r, int rt)
{
int mid = (l + r) / 2, u, v;
for (auto i: a[rt])
{
for (auto j: qq[i])
{
if (flag[j.first])
ans[j.second] += rd[r + 1] - rd[l];
}
flag[i] = 1;
}
if (l != r)
{
query(l, mid, rt * 2);
query(mid + 1, r, rt * 2 + 1);
}
for (auto i: a[rt])
flag[i] = 0;
}
} st;
inline int input()
{
int n = 0;
int f = 1;
char c = getchar_unlocked();
while (c < '0' || c > '9')
{
if (c == '-') f = -1;
c = getchar();
}
while (c >= '0' && c <= '9')
{
n = (n << 3) + (n << 1) + (c ^ 48);
c = getchar();
}
return n * f;
}
int main()
{
ios::sync_with_stdio(false);
cin.tie(nullptr);
cout.tie(nullptr);
int n, m, tmp, u, v, q;
n = input();
m = input();
d.resize(m);
for (int i = 0; i < m; i++)
{
a[i].t = input();
a[i].p = input();
d[i] = a[i].t;
}
sort(d.begin(), d.end());
int nn = unique(d.begin(), d.end()) - d.begin();
d.resize(nn);
for (int i = 0; i < m; i++)
{
tmp = lower_bound(d.begin(), d.end(), a[i].t) - d.begin() + 1;
rd[tmp] = a[i].t;
a[i].t = tmp;
if (!mp[a[i].p])
mp[a[i].p] = a[i].t;
else
{
st.updata1(mp[a[i].p], a[i].t - 1, a[i].p, 1, nn - 1, 1);
mp[a[i].p] = 0;
}
}
q = input();
for (int i = 1; i <= q; i++)
{
u = input();
v = input();
qq[u].push_back({v, i});
qq[v].push_back({u, i});
}
if (nn - 1 >= 1)
st.query(1, nn - 1, 1);
for (int i = 1; i <= q; i++)
printf("%lld\n", ans[i]);
}