标签:
2 1 1 5 10 4 2 3 1 4 4 8 1 4 6
0 1 2 1
解题思路:先把所给的值都离散化后再操作。然后就是插线问点了。
#include<bits/stdc++.h> using namespace std; const int maxn=120000; #define mid (L+R)/2 #define lson rt*2,L,mid #define rson rt*2+1,mid+1,R int a[maxn*2],aa[maxn*2],a_[maxn*2]; int x[maxn*2],y[maxn*2],q[maxn]; int f_num[maxn*4]; int discretization(int *tm,int l,int r,int key){ int m; //离散化 while(l<=r){ m=(l+r)/2; if(tm[m]<key){ l=m+1; }else if(tm[m]>key){ r=m-1; }else{ return m; } } } void update(int rt,int L,int R,int l_ran,int r_ran){ if(l_ran<=L&&R<=r_ran){ //区间更新 f_num[rt]+=1; return ; } if(l_ran<=mid){ update(lson,l_ran,r_ran); } if(r_ran>mid){ update(rson,l_ran,r_ran); } } void PushDown(int rt){ f_num[rt*2]+=f_num[rt]; f_num[rt*2+1]+=f_num[rt]; f_num[rt]=0; } int query(int rt,int L,int R,int v){ //单点查询 if(L==R){ return f_num[rt]; } if(f_num[rt]!=0) PushDown(rt); if(mid>=v){ return query(lson,v); } if(mid<v){ return query(rson,v); } } int main(){ int t; scanf("%d",&t); while(t--){ memset(f_num,0,sizeof(f_num)); int n,m,tmp; scanf("%d%d",&n,&m); int num_a=n*2+m; for(int i=0;i<num_a;i++){ scanf("%d",&tmp); a[i]=tmp; aa[i]=tmp; } sort(a,a+num_a); int num=0; a_[num++]=a[0]; for(int i=1;i<num_a;i++){ if(a[i]!=a[i-1]){ a_[num++]=a[i]; } } int num_x=0,num_y=0,num_q=0,nn=0; for(int i=0;i<n*2;i++){ if(i%2==0){ x[num_x++]=discretization(a_,0,num-1,aa[i])+1; if(nn<x[num_x-1]){ nn=x[num_x-1]; } }else{ y[num_y++]=discretization(a_,0,num-1,aa[i])+1; if(nn<y[num_y-1]){ nn=y[num_y-1]; } } } for(int i=n*2;i<num_a;i++){ q[num_q++]=discretization(a_,0,num-1,aa[i])+1; } for(int i=0;i<n;i++){ update(1,1,nn,x[i],y[i]); } for(int i=0;i<num_q;i++){ int ans=query(1,1,nn,q[i]); printf("%d\n",ans); } } return 0; }
标签:
原文地址:http://www.cnblogs.com/chengsheng/p/4470744.html