并查集/二分/greedy/1700
题意 给出a,b两个数组 求cn=ai+bj a和b每个数用且只用一次 cn字典序最小
并查集做法
开sum记录每个数的个数
把个数为0的数并入下一个数的族群中
#include<bits/stdc++.h>
#define IO ios::sync_with_stdio(false);cin.tie(0);cout.tie(0)
#define endl '\n'
#define fi for(int i=1;i<=n;i++)
#define fi2 for(int i=0;i<n;i++)
using namespace std;
typedef long long ll;
typedef vector<int> vi;
typedef set<int> si;
const ll inf=0x3f3f3f3f3f3f3f3f;
const int INF=0x3f3f3f3f;
const int MAX=2e5+10;
int gcd(int a,int b){
return b?gcd(b,a%b):a;
}
int a[MAX],b[MAX],f[MAX],c[MAX],sum[MAX];
int find(int x) {
if (f[x] == x) {
return x;
}
return f[x] = find(f[x]);
}
void merge(int x,int y){
if(find(x)!=find(y)){
f[find(x)]=find(y);
}
}
void ini(){
for(int i=0;i<MAX;i++){
f[i]=i;
}
}
int main(){
//freopen("in.txt","r",stdin);
ini();
int n;
cin>>n;
fi2{
cin>>a[i];
}
fi2{
cin>>b[i];
sum[b[i]]++;
}
fi2{
if(sum[i]==0){
merge(i,(i+1)%n);
}
}
/* fi2{
cout<<find(i)<<endl;
}*/
fi2{
// cout<<find(n-a[i])<<endl;
c[i]=(a[i]+find((n-a[i])%n))%n;
sum[find((n-a[i])%n)]--;
if( sum[find((n-a[i])%n)]==0){
merge(find((n-a[i])%n),(find((n-a[i])%n)+1)%n);
}
// cout<<find(n-a[i])<<endl;
}
fi2{
cout<<c[i]<<' ';
}
}
set二分做法
用set存b
sum=0则从set中erase然后lower bound
#include<bits/stdc++.h>
#define IO ios::sync_with_stdio(false);cin.tie(0);cout.tie(0)
#define endl '\n'
#define fi for(int i=1;i<=n;i++)
#define fi2 for(int i=0;i<n;i++)
using namespace std;
typedef long long ll;
typedef vector<int> vi;
typedef set<int> si;
const ll inf=0x3f3f3f3f3f3f3f3f;
const int INF=0x3f3f3f3f;
const int MAX=2e5+10;
int gcd(int a,int b){
return b?gcd(b,a%b):a;}
int a[MAX],b[MAX],c[MAX],sum[MAX];
int main(){
// freopen("in.txt","r",stdin);
si s;
int n;
cin>>n;
fi2{
cin>>a[i];
}
fi2{
cin>>b[i];
sum[b[i]]++;
s.insert(b[i]);
}
fi2{
int lft=(n-a[i])%n;
auto item=s.lower_bound(lft);
if(item==s.end())
item=s.begin();
auto tem=*item;
sum[tem]--;
if(sum[tem]==0)s.erase(tem);
c[i]=(tem+a[i])%n;
}
fi2{
cout<<c[i]<<' ';
}
}