http://codeforces.com/contest/1157/problem/E
(unfinished task:用权值线段树+二分 做一遍
题意:给定两个数列a和b,根据这两个数列构造出新的数列c,其中ci=(ai+bi)%n,b数列中的元素顺序可任意调换,需要求出数列c的字典序最小
思路:依次枚举数列a中的每一个元素,若在b中存在n-ai到n的数,则将满足条件的最小的那个元素从b中取出,否则取出b中最小的元素。使用multiset维护b中元素,set库中lower_bound()函数(注意该函数返回的是迭代器)可以高效的找出第一个大于等于x的数,并返回其迭代器。
code:
#include<iostream>
#include<set>
#include<cstring>
#include<cstdio>
#include<algorithm>
using namespace std;
const int maxn=2e5+5;
multiset<int>s; //维护b数组
int a[maxn];
int c[maxn];
int main(){
int n;
int x;
scanf("%d",&n);
for(int i=1;i<=n;i++){
scanf("%d",&a[i]);
}
for(int i=1;i<=n;i++){
scanf("%d",&x);
s.insert(x);
}
for(int i=1;i<=n;i++){
if(s.lower_bound(n-a[i])!=s.end()){
c[i]=(a[i]+*(s.lower_bound(n-a[i])))%n;
s.erase(s.lower_bound(n-a[i]));
}
else{
c[i]=(a[i]+*(s.lower_bound(0)))%n;
s.erase(s.lower_bound(0));
}
}
for(int i=1;i<=n;i++)
cout<<c[i]<<' ';
return 0;
}