水题,因为答案满足区间相减的性质, 即 ans<l,r> = ans<0,r> - ans[0,l-1] ,直接可以用数状数组离线查询就可以搞了
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
#define lowbit(x) x&(-x)
const int maxn=100010;
int tab[maxn],a[maxn],ans[maxn],d[maxn],n;
struct node
{
int l,r,h,id;
}q[maxn];
int cmp1(node a,node b)
{
return a.r < b.r;
}
int cmp2(node a,node b)
{
return a.l < b.l;
}
void insert(int p)
{
for(int i=p;i<=n;i+=lowbit(i)) d[i]++;
}
int query(int p)
{
int ret=0;
for(int i=p;i>0;i-=lowbit(i)) ret+=d[i];
return ret;
}
int bin(int key,int l,int r)
{
int ret=r;
while(l<=r)
{
int mid=(l+r)>>1;
if(tab[mid]<=key) ret=mid,l=mid+1;
else r=mid-1;
}
return ret+1;
}
int main()
{
int m,T,ca=1;
scanf("%d",&T);
while(T--)
{
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++) scanf("%d",&a[i]),tab[i]=a[i];
sort(tab,tab+n);
int k=unique(tab,tab+n)-tab;
for(int i=0;i<m;i++)
scanf("%d%d%d",&q[i].l,&q[i].r,&q[i].h),q[i].r++,q[i].id=i;
sort(q,q+m,cmp1);
memset(d,0,sizeof(d));
int id=1;
for(int i=0;i<m;i++)
{
while(id<=q[i].r)
{
int pos=bin(a[id],0,k-1);
insert(pos);
id++;
}
int pos=bin(q[i].h,0,k-1);
ans[q[i].id]=query(pos);
// cout<<ans[q[i].id]<<endl;
}
sort(q,q+m,cmp2);
memset(d,0,sizeof(d));
id=1;
for(int i=0;i<m;i++)
{
while(id<=q[i].l)
{
int pos=bin(a[id],0,k-1);
insert(pos);
id++;
}
int pos=bin(q[i].h,0,k-1);
ans[q[i].id]-=query(pos);
}
printf("Case %d:\n",ca++);
for(int i=0;i<m;i++)
printf("%d\n",ans[i]);
}
return 0;
}
685

被折叠的 条评论
为什么被折叠?



