Boring Counting
Time Limit: 3000MS Memory Limit: 65536KB
Problem 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)
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.
Example 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
Example Output
Case #1: 13 7 3 6 9
题目链接:SDUT 2610
裸的主席树区间查询,但是要注意一下就是离散化之后若输入的值域中有小于最小值的,即计算原位置后会出现0,因此建树若范围是1~pos.size()的话就会超时,建议改为0~pos.size();
若有大于最大值的,则离散化之后会自动替换被为最大值,然而此题这样做当然是错的,因此a不用找接近值代替而要把上限b要找接近值代替,这样一来若b大于最大值,则代替没有关系,若b等于a且均大于最大值,则会出现b比a小的情况,特判一下输出0,然后若b比最小值都要小,则直接让B等于0,也特判为输出0。
调试了一会儿终于过了,= =划分树什么的这题肯定木有这个主席树这么好用啦……再说数据结构还没学到这玩意儿……也就会个主席树了……。
最后把这组数据调通就过了……
1
13 8
1 2 3 4 5 6 7 8 9 10 11 12 13
1 13 14 14
答案应该是0,如果答案是1的话估计就是离散化位置计算出了点问题
代码:
#include <stdio.h> #include <iostream> #include <algorithm> #include <cstdlib> #include <sstream> #include <cstring> #include <bitset> #include <string> #include <deque> #include <stack> #include <cmath> #include <queue> #include <set> #include <map> using namespace std; #define INF 0x3f3f3f3f #define CLR(arr,val) memset(arr,val,sizeof(arr)) #define LC(x) (x<<1) #define RC(x) ((x<<1)+1) #define MID(x,y) ((x+y)>>1) typedef pair<int,int> pii; typedef long long LL; const double PI=acos(-1.0); const int N=50010; struct seg { int lson,rson; int cnt; }; seg T[N*20]; int root[N],tot; pii arr[N]; vector<int>pos; void update(int &cur,int ori,int l,int r,int pos) { cur=++tot; T[cur]=T[ori]; ++T[cur].cnt; if(l==r) return ; int mid=MID(l,r); if(pos<=mid) update(T[cur].lson,T[ori].lson,l,mid,pos); else update(T[cur].rson,T[ori].rson,mid+1,r,pos); } int query(int S,int E,int l,int r,int L,int R) { if(L<=l&&r<=R) return T[E].cnt-T[S].cnt; else { int mid=MID(l,r); if(R<=mid) return query(T[S].lson,T[E].lson,l,mid,L,R); else if(L>mid) return query(T[S].rson,T[E].rson,mid+1,r,L,R); else return query(T[S].lson,T[E].lson,l,mid,L,mid)+query(T[S].rson,T[E].rson,mid+1,r,mid+1,R); } } void init() { CLR(root,0); tot=0; T[0].cnt=T[0].lson=T[0].rson=0; pos.clear(); } int main(void) { int tcase,n,m,l,r,a,b,i; scanf("%d",&tcase); for (int q=1; q<=tcase; ++q) { init(); scanf("%d%d",&n,&m); for (i=1; i<=n; ++i) { scanf("%d",&arr[i].first); pos.push_back(arr[i].first); } sort(pos.begin(),pos.end()); pos.erase(unique(pos.begin(),pos.end()),pos.end()); int SZ=pos.size(); for (i=1; i<=n; ++i) { arr[i].second=lower_bound(pos.begin(),pos.end(),arr[i].first)-pos.begin()+1; update(root[i],root[i-1],0,SZ,arr[i].second); } printf("Case #%d: ",q); for (i=0; i<m; ++i) { scanf("%d%d%d%d",&l,&r,&a,&b); int A,B; A=lower_bound(pos.begin(),pos.end(),a)-pos.begin()+1; B=lower_bound(pos.begin(),pos.end(),b)-pos.begin()+1; if(pos[B-1]!=b)//上限B的位置要特别计算一下 --B; if(!B||A>B)//特判 puts("0"); else printf("%d ",query(root[l-1],root[r],0,SZ,A,B)); } } return 0; }