正确解法:
分块(超时)
1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <cmath> 5 #include <algorithm> 6 #include <set> 7 #include <map> 8 #include <vector> 9 #include <cctype> 10 #include <sstream> 11 using namespace std; 12 typedef long long ll; 13 const int inf=0x7fffffff; 14 const int N=100000+100; 15 const int M=5000+10; 16 const double PI=acos(-1.0); 17 int B=1000; 18 int n,m,a[N],num[N]; 19 int I,J,K; 20 vector<int> buck[N/1000]; 21 int main() 22 { 23 scanf("%d %d",&n,&m); 24 for(int i=0;i<n;i++) 25 { 26 scanf("%d",&a[i]); 27 num[i]=a[i]; 28 buck[i/B].push_back(a[i]); 29 } 30 sort(num,num+n); 31 for(int i=0;i<n/B;i++) 32 sort(buck[i].begin(),buck[i].end()); 33 for(int i=0;i<m;i++) 34 { 35 scanf("%d %d %d",&I,&J,&K); 36 int lb=0,ub=n-1; 37 while(lb<=ub) 38 { 39 int md= lb+ub >>1; 40 int x=num[md]; 41 int tl=I-1,tr=J,c=0; 42 while(tl<tr &&tl%B!=0) if(a[tl++]<=x) c++; 43 while(tl<tr &&tr%B!=0) if(a[--tr]<=x) c++; 44 while(tl<tr) 45 { 46 int b=tl/B; 47 c+=upper_bound(buck[b].begin(),buck[b].end(),x)-buck[b].begin(); 48 tl+=B; 49 } 50 if(c>=K) ub=md-1; 51 else lb=md+1; 52 } 53 printf("%d ",num[lb]); 54 } 55 56 57 return 0; 58 }
主席树:
1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <cmath> 5 #include <algorithm> 6 #include <set> 7 #include <map> 8 #include <vector> 9 #include <cctype> 10 #include <sstream> 11 using namespace std; 12 typedef long long ll; 13 const int inf=0x7fffffff; 14 const int N=100000+100; 15 const int M=5000+10; 16 const double PI=acos(-1.0); 17 int n,m,a[N],num[N]; 18 int I,J,K; 19 vector<int>buck[(1<<18)-1]; 20 void build(int rt,int l,int r) 21 { 22 if(l==r) 23 { 24 buck[rt].push_back(a[l]); 25 return ; 26 } 27 int m= l+r >>1; 28 build(rt<<1,l,m); 29 build(rt<<1|1,m+1,r); 30 buck[rt].resize(r-l+1); 31 merge(buck[rt<<1].begin(),buck[rt<<1].end(),buck[rt<<1|1].begin(),buck[rt<<1|1].end(),buck[rt].begin()); 32 } 33 int query(int L,int R,int x,int rt,int l,int r) 34 { 35 if(R<l||r<L) 36 return 0; 37 if(L<=l&&r<=R) 38 return upper_bound(buck[rt].begin(),buck[rt].end(),x)-buck[rt].begin(); 39 int ans=0,m=l+r >>1; 40 ans+=query(L,R,x,rt<<1,l,m); 41 ans+=query(L,R,x,rt<<1|1,m+1,r); 42 return ans; 43 } 44 int main() 45 { 46 scanf("%d %d",&n,&m); 47 for(int i=1;i<=n;i++) 48 { 49 scanf("%d",&a[i]); 50 num[i]=a[i]; 51 } 52 sort(num+1,num+1+n); 53 build(1,1,n); 54 while(m--) 55 { 56 scanf("%d %d %d",&I,&J,&K); 57 //J++; 58 int lb=1,ub=n; 59 while(lb<=ub) 60 { 61 int md=lb+ub >>1; 62 int c=query(I,J,num[md],1,1,n); 63 if(c>=K) ub=md-1; 64 else lb=md+1; 65 } 66 printf("%d ",num[lb]); 67 } 68 69 return 0; 70 }