题解:类似与超级钢琴的做法 直接用堆维护即可 (
#include <algorithm>
#include <iostream>
#include <cstring>
#include <cstdio>
#include <vector>
#include <stack>
#include <queue>
#include <cmath>
#include <set>
#include <map>
#define mp make_pair
#define pb push_back
#define pii pair<int,int>
#define link(x) for(edge *j=h[x];j;j=j->next)
#define inc(i,l,r) for(int i=l;i<=r;i++)
#define dec(i,r,l) for(int i=r;i>=l;i--)
const int MAXN=3e5+10;
const double eps=1e-8;
#define ll long long
using namespace std;
struct edge{int t,v;edge*next;}e[MAXN<<1],*h[MAXN],*o=e;
void add(int x,int y,int vul){o->t=y;o->v=vul;o->next=h[x];h[x]=o++;}
ll read(){
ll x=0,f=1;char ch=getchar();
while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();}
while(isdigit(ch))x=x*10+ch-'0',ch=getchar();
return x*f;
}
int n,k,cnt;
int a[MAXN],rt[MAXN],tag[MAXN*32];
typedef struct node{
int l,r,sum;
}node;
node d[MAXN*32];
void insert(int x,int k,int id){
for(int i=30;i>=0;i--){
if(k&(1<<i)){
int t=++cnt;d[t]=d[d[x].r];d[x].r=t;d[t].sum++;
x=t;
}
else{
int t=++cnt;d[t]=d[d[x].l];d[x].l=t;d[t].sum++;
x=t;
}
}
tag[x]=id;
}
pair<int,int> querty(int x,int y,int k){
int res=0;
for(int i=30;i>=0;i--){
if(k&(1<<i)){
if(d[d[y].r].sum-d[d[x].r].sum)res+=(1<<i),x=d[x].r,y=d[y].r;
else x=d[x].l,y=d[y].l;
}
else{
if(d[d[y].l].sum-d[d[x].l].sum)x=d[x].l,y=d[y].l;
else res+=(1<<i),x=d[x].r,y=d[y].r;
}
}
res^=k;
return mp(tag[y],res);
}
typedef struct Tmp{
int pos,l,r,key,aim;
friend bool operator<(Tmp aa,Tmp bb){return aa.key>bb.key;}
}Tmp;
priority_queue<Tmp>que;
vector<int>vec;
int main(){
n=read();k=read();cnt=0;
rt[0]=++cnt;insert(rt[0],0,0);
inc(i,1,n)a[i]=read(),rt[i]=++cnt,d[rt[i]]=d[rt[i-1]],insert(rt[i],a[i],i);
inc(i,2,n){
pair<int,int> t=querty(rt[0],rt[i-1],a[i]);
que.push((Tmp){t.first,1,i-1,t.second,i});
}
pair<int,int> t1;
for(int i=1;i<=k;i++){
vec.pb((que.top()).key);
Tmp t=que.top();que.pop();printf("%d ",t.key);
if(t.pos>t.l)t1=querty(rt[t.l-1],rt[t.pos-1],a[t.aim]),que.push((Tmp){t1.first,t.l,t.pos-1,t1.second,t.aim});
if(t.pos<t.r)t1=querty(rt[t.pos],rt[t.r],a[t.aim]),que.push((Tmp){t1.first,t.pos+1,t.r,t1.second,t.aim});
}
}
3689: 异或之
Time Limit: 10 Sec Memory Limit: 256 MB
Submit: 550 Solved: 269
[Submit][Status][Discuss]
Description
给定n个非负整数A[1], A[2], ……, A[n]。
对于每对(i, j)满足1 <= i < j <= n,得到一个新的数A[i] xor A[j],这样共有n*(n-1)/2个新的数。求这些数(不包含A[i])中前k小的数。
注:xor对应于pascal中的“xor”,C++中的“^”。
Input
第一行2个正整数 n,k,如题所述。
以下n行,每行一个非负整数表示A[i]。
Output
共一行k个数,表示前k小的数。
Sample Input
4 5
1
1
3
4
Sample Output
0 2 2 5 5
HINT
【样例解释】
1 xor 1 = 0 (A[1] xor A[2])
1 xor 3 = 2 (A[1] xor A[3])
1 xor 4 = 5 (A[1] xor A[4])
1 xor 3 = 2 (A[2] xor A[3])
1 xor 4 = 5 (A[2] xor A[4])
3 xor 4 = 7 (A[3] xor A[4])
前5小的数:0 2 2 5 5
【数据范围】
对于100%的数据,2 <= n <= 100000; 1 <= k <= min{250000, n*(n-1)/2};
0 <= A[i] < 2^31
转载于:https://www.cnblogs.com/wang9897/p/9723096.html
原文链接:https://blog.csdn.net/weixin_30342827/article/details/97897042
本站声明:网站内容来源于网络,如有侵权,请联系我们,我们将及时处理。
还没有人抢沙发呢~