求助ABC365G题复杂度
  • 板块学术版
  • 楼主Alliy666
  • 当前回复0
  • 已保存回复0
  • 发布时间2024/8/3 22:23
  • 上次更新2024/8/4 08:57:59
查看原帖
求助ABC365G题复杂度
908741
Alliy666楼主2024/8/3 22:23

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]);
}
2024/8/3 22:23
加载中...