Codeforces Round 857 (Div. 2)
C (构造 数论)
https://codeforces.com/contest/1801/problem/A
题意:给定一个nm矩阵,要求任意一个22方格所有数异或和等于其所有对角22方格异或和,并要求不同的数尽量多。
n,m<=200
题解:不妨加强条件,对任意一个22方格使其异或和为0,并且使得每一个数均不相同,即可满足条件。
注意到22方格中有四个数,而对于0~2^k-1连续的数异或和为0,故我们考虑使得任意一个22方格满足其末位连续。即为0 1 2 3。
我们首先对两行进行构造,当按照上述填法时可以保证任意2*2方格异或和=0,而每2行最多用去400个数,故我们只需每次从512的倍数开始赋值即可使得每相邻两行的低8位连续,高位可消去。
代码:
#include<bits/stdc++.h>
#define int long long
using namespace std;
int a[300][300];
int check(int x){
int k=1;
while(1){
if(x<=(1<<k)&&x>(1<<(k-1))) return (1<<k);
else k++;
}
}
void solve(){
unsigned long long cnt=0;
int p=512;
int n,m;cin>>n>>m;
cout<<n*m<<endl;
for(int i=1;i<=n;i+=2){
for(int j=1;j<=m;j+=2){
a[i][j]=cnt,a[i][j+1]=cnt+1,a[i+1][j]=cnt+2,a[i+1][j+1]=cnt+3;
cnt+=4;
}
cnt=p;
p+=512;
}
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
cout<<a[i][j];
if(j!=m) cout<<" ";
}
cout<<endl;
}
}
signed main(){
std::ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
int T;cin>>T;
while(T--) solve();
}
D (贪心)
https://codeforces.com/contest/1802/problem/D
题意:有n个商店,在每个商店必须买一个物品,可以买给A花费ai也可以买给B花费bi,求二者礼物中各自最贵的礼物的最小差值,要求每个人都要有礼物。
n<=5e5
题解:观察数据范围复杂度应该是nlogn,由于最大值会覆盖,我们必然需要按大小排序,由于每人都要有礼物,所以我们枚举其中某一个的最大值。我们对ai从小到大排序,然后枚举ai最大值,对于大于i的位置,必然选取b,对于小于i的位置,可选可不选。
对于>i位置,如果最大值maxb>ai,那么我们直接选取其作为最大值即可,否则我们二分剩余的b,得到最接近ai的数以更新答案。可以用两个mutiset维护小于i位置的b和大于i位置的b,复杂度为O(nlogn)。
代码:
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N=5e5+100;
void solve(){
int n;cin>>n;
vector<pair<int,int> >a(n);
multiset<int> s1,s2;
for(int i=0;i<n;i++){
cin>>a[i].first>>a[i].second;
s2.insert(a[i].second);
}
sort(a.begin(),a.end());
int ans=1e9;
for(int i=0;i<n;i++){
auto [x,y]=a[i];
s2.erase(s2.lower_bound(y));
if(!s2.empty()){
int mx=*prev(s2.end());
if(mx>=x) ans=min(mx-x,ans);
else{
ans=min(ans,x-mx);
auto it=s1.lower_bound(x);
if(it!=s1.end()) ans=min(ans,*it-x);
if(it!=s1.begin()) ans=min(ans,x-*prev(it));
}
}
else{
auto it=s1.lower_bound(x);
if(it!=s1.end()) ans=min(ans,*it-x);
if(it!=s1.begin()) ans=min(ans,x-*prev(it));
}
s1.insert(y);
}
cout<<ans<<endl;
}
signed main(){
int T;cin>>T;
while(T--) solve();
}