NamomoCamp Daily 6
代码源oj网址http://oj.daimayuan.top/course/10/problem/464
题解:
离散化+树状数组。
因为 A i A_i Ai最大为1e9,而 N N N最大为1e6,离散化之后最大的值也为1e6。
对于区间 [ L i , R i ] [L_i,R_i] [Li,Ri],统计不大于 H i H_i Hi的个数,我们可以将小于等于 H i H_i Hi的位置全部赋值为1,那么求区间内的个数问题可以转化成求区间和的问题。
那我们离散化后从小到大去赋值。当当前赋值的值是要求的 H i H_i Hi时,便去求区间求和。
代码:
代码源
// Good Good Study, Day Day AC.
#include <iostream>
#include <stdio.h>
#include <cstdio>
#include <stdlib.h>
#include <string>
#include <string.h>
#include <cstring>
#include <math.h>
#include <cmath>
#include <queue>
#include <deque>
#include <stack>
#include <vector>
#include <map>
#include <algorithm>
#include <unordered_map>
#include <unordered_set>
#define ffor(i,a,b) for(int i=(a) ;i<=(b) ;i++)
#define rrep(i,a,b) for(int i=(a) ;i>=(b) ;i--)
#define mst(v,s) memset(v,s,sizeof(v))
#define IOS ios::sync_with_stdio(false),cin.tie(0)
#define ll long long
#define INF 0x7f7f7f7f7f7f7f7f
#define inf 0x7f7f7f7f
#define PII pair<int,int>
#define int long long
using namespace std;
const int N = 1e5 + 5;
int n, T, m, qi, qnum;
int a[N], t[N], num[N];
struct Ques {
int l, r, h, ans, id;
}q[N];
vector<int> add;
vector<int> v[N];
unordered_set<int> s;
void ready()
{
IOS;
cin >> T;
}
int lowbite(int x) {
return x & (-x);
}
int find_(int x)
{
int l = 0, r = add.size() - 1;
while (l < r)
{
int mid = l + r >> 1;
if (add[mid] >= x) r = mid;
else l = mid + 1;
}
return r + 1;
}
bool cmp(Ques i, Ques j) {
return i.h < j.h;
}
bool idd(Ques i, Ques j) {
return i.id < j.id;
}
void addinto(int i)
{
for (auto item : v[i]) {
int now = item;
while (now <= n) {
t[now]++;
now += lowbite(now);
}
}
v[i].clear();
}
int get_ans(int x) {
int res = 0;
while (x) {
res += t[x];
x -= lowbite(x);
}
return res;
}
void work()
{
cin >> n >> m;
ffor(i, 1, n) {
cin >> a[i];
add.push_back(a[i]);
s.insert(a[i]);
num[i] = a[i];
}
sort(add.begin(), add.end());
add.erase(unique(add.begin(), add.end()), add.end());
ffor(i, 1, n) {
a[i] = find_(a[i]);
v[a[i]].push_back(i);
}
ffor(i, 1, m) {
cin >> q[i].l >> q[i].r >> q[i].h;
q[i].id = i;
q[i].ans = 0;
}
sort(q + 1, q + m + 1, cmp);
int qi = 1;
for (int i = 1; i <= add.size(); i++) {
int bef=num[v[i][0]];
while (qi <= m && bef > q[qi].h) {
q[qi].ans = get_ans(q[qi].r) - get_ans(q[qi].l - 1);
qi++;
}
addinto(i);
}
while (qi <= m) {
q[qi].ans = get_ans(q[qi].r) - get_ans(q[qi].l - 1);
qi++;
}
sort(q + 1, q + m + 1, idd);
ffor(i, 1, m) cout << q[i].ans << ' ';
cout << '\n';
add.clear();
s.clear();
mst(t, 0);
}
signed main()
{
ready();
while (T--)
work();
return 0;
}