数数(代码源每日一题)

数数(离线树状数组处理可持久化问题)

题意

给定 n(1<=n<=105) 长度的数组 ai(0<=ai<=109), 进行 m 次询问,格式为 l,r,v,每次询问 l<=i<=r ,有多少 ai<=v

数数 - 题目 - Daimayuan Online Judge

思路

可先用前缀和的思想,每次询问的答案为 前 r 个数中小于等于 v 的个数 - 前 l1 个数中小于等于 v 的个数

因此可以用可持久化线段树来处理

然而本题中,对于每次询问,大于 v 的元素无需考虑

因此也可将询问的 v 从小到大排序,每次只将小于等于 v 的元素插入树状数组中,也可用 nlogn 复杂度解决

代码

#include <iostream>
#include <cstring>
#include <algorithm>
#include <vector>
#include <map>
using namespace std;
typedef long long ll;
typedef pair<int, int> PII;
const int N = 2e5 + 10;
int n, m, ans[N], tr[N], num;
vector<int> G[N];
vector<int> alls;
PII lastp[N];
struct Query
{
	int l, r, v, id;
	bool operator<(const Query &x) const
	{
		return v < x.v;
	}
}q[N];

void clean()
{
	alls.clear();
	for (int i = 0; i <= num; i++)
	{
		tr[i] = 0;
		G[i].clear();
	}
}
int find(int x)
{
	return lower_bound(alls.begin(), alls.end(), x) - alls.begin() + 1;
}

int lowbit(int x)
{
	return x & -x;
}

void add(int idx)
{
	for (int i = idx; i <= num; i += lowbit(i))
		tr[i] += 1;
}

int sum(int idx)
{
	int res = 0;
	for (int i = idx; i; i -= lowbit(i))
		res += tr[i];
	return res;
}
int main()
{
	ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);
	int T;
	cin >> T;
	while(T--)
	{
		cin >> n >> m;
		for (int i = 1; i <= n; i++)
		{
			int x;
			cin >> x;
			alls.push_back(x);
			lastp[i] = {x, i};
		}
		for (int i = 1; i <= m; i++)
		{
			int l, r, x;
			cin >> l >> r >> x;
			q[i] = {l, r, x, i};
			alls.push_back(x);
		}
		
		
		sort(alls.begin(), alls.end());
		alls.erase(unique(alls.begin(), alls.end()), alls.end());
		
		num = alls.size();
		for (int i = 1; i <= n; i++)
		{
			int x = find(lastp[i].first);
			G[x].push_back(lastp[i].second);
		}
		
		
		sort(q + 1, q + m + 1);
		int h = 0;
		for (int i = 1; i <= m; i++)
		{
			int v = q[i].v, l = q[i].l, r = q[i].r, id = q[i].id;
			v = find(v);
			for (int j = h+1; j <= v; j++)
			{
				for (auto k : G[j])
					add(k);
			}
			h = v;
			ans[id] = sum(r) - sum(l-1);
		}
		for (int i = 1; i <= m; i++)
			cout << ans[i] << " ";
		cout << endl;
		clean();
	}
	return 0;
}
posted @   hzy0227  阅读(66)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 25岁的心里话
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
· 一起来玩mcp_server_sqlite,让AI帮你做增删改查!!
· 零经验选手,Compose 一天开发一款小游戏!
点击右上角即可分享
微信分享提示