我好菜,佬们好厉害。
比赛的时候正好是电路实验就错过了啊啊啊啊
今天中午补题,大概一个小时A了三道,D2实在想不起来了
看别人的代码都是拿线段树写的,(鬼知道我线段树多久没用过了啊啊啊)
写到自闭叻。
主要就是用线段树二分寻找数组中某位置 x ,满足1 ~ x 的和为 pos ,还是01与线段树
int n,m;
struct IN {int x,id;} a[N],b[N];
struct INN {int k,pos,id,ans;} q[N];
int cmp(IN aa,IN bb)
{
if(aa.x==bb.x) return aa.id<bb.id;
return aa.x>bb.x;
}
int cmp1(INN aa,INN bb){return aa.k<bb.k;}
int cmp2(INN aa,INN bb){return aa.id<bb.id;}
struct TREE
{
#define ls rt<< 1,l,mid
#define rs rt<<1 | 1,mid+1,r
int sum[N<<2];
void init(){for(int i=0;i<=n;++i) sum[i]=0;}
void update(int rt,int l,int r,int pos)
{
if(l==r)
{
sum[rt]=1;//噗,一开始更新成sum[l]我是咋想的
return ;
}
int mid=(l+r)>>1;
if(pos<=mid) update(ls,pos);
else update(rs,pos);
sum[rt]=sum[rt<<1]+sum[rt<<1 | 1];
}
int que(int rt,int l,int r,int pos)
{
if(l==r) return a[l].x;
int mid=(l+r)>>1;
if(sum[rt<<1]>=pos) return que(ls,pos);
else return que(rs,pos-sum[rt<<1]); //记得剪掉左子树
}
}tree;
int main()
{
fast;
cin>>n;
for(int i=1;i<=n;++i)
{
cin>>a[i].x;
a[i].id=i;
b[i]=a[i];
}
sort(b+1,b+n+1,cmp);
cin>>m;
for (int i = 1; i <= m; ++i) cin>>q[i].k>>q[i].pos,q[i].id=i;
sort(q+1,q+m+1,cmp1);
int now=0;
tree.init();
for (int i = 1; i <= m; ++i)
{
while(now<q[i].k) tree.update(1,1,n,b[++now].id);
q[i].ans=tree.que(1,1,n,q[i].pos);
}
sort(q+1,q+m+1,cmp2);
for (int i = 1; i <= m; i++)
cout<<q[i].ans<<endl;
//stop;
return 0;
} 
京公网安备 11010502036488号