Boring Counting
Time Limit: 3000 MS Memory Limit: 32768 K
Total Submit: 67(21 users) Total Accepted: 5(5 users) Rating: Special Judge: No
Description
In this problem you are given a number sequence P consisting of N integer and Pi is the ith element in the sequence. Now you task is to answer a list of queries, for each query, please tell us among [L, R], how many Pi is not less than A and not greater than B( L<= i <= R). In other words, your task is to count the number of Pi (L <= i <= R, A <= Pi <= B).
Input
In the first line there is an integer T (1 < T <= 50), indicates the number of test cases.
For each case, the first line contains two numbers N and M (1 <= N, M <= 50000), the size of sequence P, the number of queries. The second line contains N numbers Pi(1 <= Pi <= 10^9), the number sequence P. Then there are M lines, each line contains four number L, R, A, B(1 <= L, R <= n, 1 <= A, B <= 10^9)
Output
For each case, at first output a line ‘Case #c:’, c is the case number start from 1. Then for each query output a line contains the answer.
Sample Input
1
13 5
6 9 5 2 3 6 8 7 3 2 5 1 4
1 13 1 10
1 13 3 6
3 6 3 6
2 8 2 8
1 9 1 9
Sample Output
Case #1:
13
7
3
6
9
题意:问[l,r]内>=a&&<=b的数的个数。
题解:
所需技能:主席树+二分+离散化。
先建一颗主席树便于我们快速求区间[L,R](数据过大,需要离散化),然后二分找到离散化后>=ad的最小值和<=b的最大值,然后统计一下就好。
代码:
#include<stdio.h>
#include<stdlib.h>
#include<algorithm>
#include<iostream>
#include<vector>
#include<map>
#include<set>
#include<math.h>
#include<string.h>
#define ll long long
using namespace std;
const int N=60000;
struct node{int l,r,sum;} T[N*40];
int n,t,m,x,y,k,cnt,l,r,tmp,root[N],a[N];
vector<int>p;
int getid(int x){return lower_bound(p.begin(),p.end(),x)-p.begin()+1;};
void update(int l,int r,int &x,int y,int pos)
{
T[++cnt]=T[y],T[cnt].sum++,x=cnt;
if(l==r) return;
int mid=(r+l)>>1;
if(pos<=mid) update(l,mid,T[x].l,T[y].l,pos);
else
update(mid+1,r,T[x].r,T[y].r,pos);
}
int query(int L,int R,int l,int r,int x,int y)
{
if(L<=l&&R>=r) return T[y].sum-T[x].sum;
int mid=(r+l)>>1;
int res=0;
if(L<=mid) res+=query(L,R,l,mid,T[x].l,T[y].l);
if(R>mid) res+=query(L,R,mid+1,r,T[x].r,T[y].r);
return res;
}
int solo1(int x)
{
int l=0,r=tmp-1;
int ans=-1;
while(r>=l)
{
int mid=(r+l)>>1;
if(p[mid]>=x)
{
ans=mid;
r=mid-1;
}
else
l=mid+1;
}
return ans;
}
int solo2(int x)
{
int l=0,r=tmp-1;
int ans=-1;
while(r>=l)
{
int mid=(r+l)>>1;
if(p[mid]<=x)
{
ans=mid;
l=mid+1;
}
else
r=mid-1;
}
return ans;
}
int main()
{
scanf("%d",&t);
for(int cas=1; cas<=t; cas++)
{
p.clear();
cnt=1;
memset(root,0,sizeof(root));
memset(T,0,sizeof(T));
printf("Case #%d:\n",cas);
scanf("%d%d",&n,&m);
for(int i=1; i<=n; i++) scanf("%d",&a[i]),p.push_back(a[i]);
sort(p.begin(),p.end()),p.erase(unique(p.begin(),p.end()),p.end());
tmp=p.size();
for(int i=1; i<=n; i++) update(1,n,root[i],root[i-1],getid(a[i]));
for(int i=1; i<=m; i++)
{
scanf("%d%d%d%d",&x,&y,&l,&r);
int u=solo1(l);
int v=solo2(r);
if(u==-1||v==-1||x>y)
{
printf("0\n");
}
else
{
u++,v++;
printf("%d\n",query(u,v,1,n,root[x-1],root[y]));
}
}
}
return 0;
}