分桶法和平方分割
其实我觉得这方法效率真心不高…
poj 2104 K-th Number
这题我照着模板写t了,网上的ac代码用了11秒,先挂上吧…
#include<cstdio>
#include<cstring>
#include<cmath>
#include<iostream>
#include<iomanip>
#include<algorithm>
#include<stack>
#include<queue>
#include<cstdlib>
#include<string>
#include<vector>
#include<list>
#include<map>
#include<set>
#define fi first
#define se second
#define pb push_back
#define me(a,b) memset(a,b,sizeof(a))
#define INIT() std::ios::sync_with_stdio(false)
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int,int>P;
const int MAX_N=100000+5;
const int MAX_M=100000+5;
const int INF=0x7fffffff;
const int inf=1000000000;
const double EPS=1e-6;
const ull base=123;
const ll mod=998244353;
const double pi=4*atan(1.0);
int a[MAX_N];
int num[MAX_N];
int B=1000;
vector<int>v[300];
int main()
{
int n,m;
scanf("%d%d",&n,&m);
int i;
for(i=0;i<n;i++)
{
scanf("%d",&a[i]);
num[i]=a[i];
v[i/B].pb(a[i]);
}
sort(num,num+n);
for(i=0;i<n/B;i++)
{
sort(v[i].begin(),v[i].end());
}
while(m--)
{
int l,r,k;
scanf("%d%d%d",&l,&r,&k);
l--;
int left=0;
int right=n-1;
int mid=(left+right)>>1;
while(left<=right)
{
int x=num[mid];
int tl=l;
int tr=r;
int c=0;
while(tl<tr&&tl%B)
{
if(a[tl++]<=x)c++;
}
while(tl<tr&&tr%B)
{
if(a[--tr]<=x)c++;
}
while(tl<tr)
{
int b=tl/B;
c+=upper_bound(v[b].begin(),v[b].end(),x)-v[b].begin();
tl+=B;
}
if(c>=k)
right=mid-1;
else
left=mid+1;
mid=(left+right)>>1;
//cout<<mid<<endl;
}
printf("%d\n",num[mid+1]);
}
}