换个角度思考
换个角度思考
https://ac.nowcoder.com/acm/problem/19427
///直接我们开一个pair然后存每个数 每个数的下标,
///然后把M次查询的按照K升序排序一次,pair按照序列升序排序,
///然后就是利用树状数组来搞,离线做,我们只需要比较一次序列和K的大小就可以,
///因为我们是利用树状数组来做,那么[l,r]的区间答案,我们是不是可以直接[1,r]-[1,l-1]这样直接求出来。
///因为我们的K是排序了,然后每次处理的K都是由小的开始比较 ,所以后面的K可以直接使用之前区间的比较的每个dou[].
#include <bits/stdc++.h>
#define fio ios_base::sync_with_stdio(0);cin.tie(0);cout.tie(0);
#define debug(x) cout << #x << ": " << x << endl;
#define debug1(x) cout<<"xxx"<<endl;
#define ll long long
#define ull unsigned long long
#pragma GCC optimize("Ofast","inline","-ffast-math")
#pragma GCC target("avx,sse2,sse3,sse4,mmx")
#define mse(a,b) memset(a,b,sizeof a);
using namespace std;
const int maxx=1e6+100;
const int mod=1e9+7;
struct node
{
int l,r,x,id;
bool operator <(const node &a)
{
return x<a.x;
}
};
node q[maxx];
pair<int,int>a[maxx];
int n,m;
int dou[maxx];
int oo[maxx];
int lowbit(int x)
{
return x&(-x);
}
void update(int x)
{
while(x<=n)
{
oo[x]++;
x+=lowbit(x);
}
}
int query(int x)
{
int res=0;
while(x>0)
{
// cout<<123<<endl;
res+=oo[x];
x-=lowbit(x);
}
return res;
}
int main()
{
fio;
scanf("%d%d",&n,&m);
for(int i = 1;i <= n;i ++)
scanf("%d",&a[i].first),a[i].second = i;
sort(a + 1,a + 1 + n);///按照值的大小排序
for(int i = 1;i <= m;i ++)///保存询问 并且保留下标
{
scanf("%d%d%d",&q[i].l,&q[i].r,&q[i].x);
q[i].id = i;
}
sort(q + 1, q + m + 1);///按照值排序
int k = 1;
for(int i = 1;i <= m;i ++)
{
while(a[k].first <= q[i].x && k <= n)///当前值小于查询的值就更新
{
update(a[k].second);///用该数在数组中位置维护
k ++ ;
}
dou[q[i].id] = query(q[i].r) - query(q[i].l - 1);///区间查询
}
for(int i = 1;i <= m;i ++)///离线回答
printf("%d\n",dou[i]);
return 0;
}
/*
5 3
1 2 3 4 5
1 3 5
1 3 5
1 3 5
*/
查看12道真题和解析
字节跳动公司福利 1309人发布