http://acm.hdu.edu.cn/showproblem.php?pid=4417
2012hangzhouonline
给出一个大小 n 的数组,m 组操作,(n,m < = 10 w ). 每组操作是3个数,L,R,H ,求数组区间[L,R]中小于等于H的数有多少个?
先将输入数据按数值大小排序,包括查询的数据。然后对排序后的数据除查询数据外按次序插入,插入位置即为原在数组中的位置,由于前面插入的数据必然不大于要查询数据,故每次查询统计某段区间元素个数即可。线段树或树状数组。
#include <cstdio>
#include <cstring>
#include <cmath>
#include <map>
#include <set>
//#include <vector>
#include <iostream>
#include <algorithm>
#include<string>
using namespace std;
//const double ePs=1e-7;
//const double INF=1e50;
//const double Pi=acos(-1);
#define NN 131072
#define INF 0x7ffffff
#define N 100005
struct data
{
int d;
bool f;
int s,t;
int num;
}a[2*N];
struct tree
{
int s,t,sum;
}t[NN*2+5];
int n,s,c[N];
bool cmp(const data &a1,const data &b)
{
if (a1.d!=b.d) return a1.d<b.d;
else return a1.f;
}
void build(int m,int p,int q)
{
t[m].s=p;
t[m].t=q;
t[m].sum=0;
if (m<NN)
{
int mid=(p+q)/2;
build(2*m,p,mid);
build(2*m+1,mid+1,q);
}
}
void Update(int m)
{
while (m>0)
{
t[m].sum++;
m/=2;
}
}
void Insert(int m)
{
t[m+NN-1].sum++;
Update((m+NN-1)/2);
}
void Query(int m,int p,int q)
{
if (t[m].s==p && t[m].t==q)
{
s+=t[m].sum;
return ;
}
if (q<=t[2*m].t) Query(2*m,p,q);
else if (p>=t[2*m+1].s) Query(2*m+1,p,q);
else
{
Query(2*m,p,t[2*m].t);
Query(2*m+1,t[2*m+1].s,q);
}
}
int main()
{
//freopen("a","r",stdin);
int T,kk,m,i;
scanf("%d",&T);
for (kk=1;kk<=T;kk++)
{
printf("Case %d:\n",kk);
scanf("%d%d",&n,&m);
for (i=1;i<=n;i++)
{
scanf("%d",&a[i].d);
a[i].s=i;
a[i].f=true;
}
for (i=n+1;i<=n+m;i++)
{
scanf("%d%d%d",&a[i].s,&a[i].t,&a[i].d);
a[i].s++;
a[i].t++;
a[i].f=false;
a[i].num=i-n;
}
sort(a+1,a+n+m+1,cmp);
build(1,1,NN);
for (i=1;i<=n+m;i++)
if (a[i].f) Insert(a[i].s);
else
{
s=0;
Query(1,a[i].s,a[i].t);
c[a[i].num]=s;
}
for (i=1;i<=m;i++) printf("%d\n",c[i]);
}
return 0;
}
#include <cstdio>
#include <cstring>
#include <cmath>
#include <map>
#include <set>
//#include <vector>
#include <iostream>
#include <algorithm>
#include<string>
using namespace std;
//const double ePs=1e-7;
//const double INF=1e50;
//const double Pi=acos(-1);
#define NN 131072
#define INF 0x7ffffff
#define N 100005
struct data
{
int d;
bool f;
int s,t;
int num;
}a[2*N];
int t[N];
int n,s,c[N];
bool cmp(const data &a1,const data &b)
{
if (a1.d!=b.d) return a1.d<b.d;
else return a1.f;
}
void Add(int p,int d)
{
while (p<=n)
{
t[p]+=d;
p+=p&(-p);
}
}
int sum(int p)
{
int ret=0;
while (p)
{
ret+=t[p];
p-=p&(-p);
}
return ret;
}
int main()
{
//freopen("a","r",stdin);
int T,kk,m,i;
scanf("%d",&T);
for (kk=1;kk<=T;kk++)
{
printf("Case %d:\n",kk);
scanf("%d%d",&n,&m);
for (i=1;i<=n;i++)
{
scanf("%d",&a[i].d);
a[i].s=i;
a[i].f=true;
}
for (i=n+1;i<=n+m;i++)
{
scanf("%d%d%d",&a[i].s,&a[i].t,&a[i].d);
a[i].s++;
a[i].t++;
a[i].f=false;
a[i].num=i-n;
}
sort(a+1,a+n+m+1,cmp);
for (i=0;i<=n;i++) t[i]=0;
for (i=1;i<=n+m;i++)
if (a[i].f) Add(a[i].s,1);
else c[a[i].num]=sum(a[i].t)-sum(a[i].s-1);
for (i=1;i<=m;i++) printf("%d\n",c[i]);
}
return 0;
}