Codeforces Round 908 (Div. 2)
A. Secret Sport
题目保证s一定是合法序列,所以最后一场获胜的人使游戏结束,他就是winner
B. Two Out of Three
判断是否有两组及以上相同数即可,然后任意选两种情况赋值
C. Anonymous Informant
根据题目反向模拟,即对于 b i b_i bi,若 b i b_i bi向右滑动 b i b_i bi位后的下标正好等于 b i b_i bi,则b可经过一次变换得来。仔细观察可以发现只有 b n b_n bn可能会满足 “ b i b_i bi向右滑动 b i b_i bi位后的下标正好等于 b i b_i bi”,所以可以求出当前b最多可逆向滑动多少次(或者无限次),与k比较即可
#include<bits/stdc++.h>
using namespace std;
#define int long long
#define IO ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);
#define endl '\n'
#define all(x) (x).begin(), (x).end()
const int N = 2e5 + 10;
int n, k;
void solve(){
cin >> n >> k;
vector<int>a(n);
vector<int>vis(n);
for(int i = 0;i < n;i++) cin >> a[i];
int cnt = 0;
int p = n - 1;
while(1){
if(a[p] > n) break;
if(vis[p]){
cout << "Yes\n";
return;
}
vis[p] = 1;
p -= a[p];
if(p < 0) p += n;
cnt++;
}
cout << (cnt >= k ? "Yes\n" : "No\n");
}
signed main(){
IO;
int t = 1;
cin >> t;
while(t--) solve();
return 0;
}
D. Neutral Tonality
a中已存在的逆序对数无法减小,所以对于每个 b i b_i bi只要将它放在第一个小于等于 b i b_i bi的 a i a_i ai前面就不会使逆序对数增加,没有小于 b i b_i bi的数就放在最后。但是直接查找每个小于 b i b_i bi的 a i a_i ai较难,并且b数组可重排,所以可以将b排序,对于每个 a i a_i ai二分查找第一个大于等于它的 b i b_i bi,将这个 b i b_i bi即 b i b_i bi后面的元素都放到 a i a_i ai前面
#include<bits/stdc++.h>
using namespace std;
#define int long long
#define IO ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);
#define endl '\n'
#define all(x) (x).begin(), (x).end()
const int N = 2e5 + 10;
int n, m;
void solve(){
cin >> n >> m;
vector<int>a(n), b(m);
int mn = 1e10;
for(auto& e : a) cin >> e, mn = min(mn, e);
for(auto& e : b) cin >> e;
sort(all(b));
int len = m;
bool f = true;
for(int i = 0;i < n;i++){
int p = lower_bound(b.begin(), b.begin() + len, a[i]) - b.begin();
for(int j = len - 1;j >= p;j--) cout << b[j] << ' ';
len = p;
cout << a[i] << ' ';
}
for(int i = len - 1;i >= 0;i--) cout << b[i] << ' ';
cout << endl;
}
signed main(){
IO;
int t = 1;
cin >> t;
while(t--) solve();
return 0;
}
E. Freedom of Choice
求出X的最大和最小大小R,L,若(R-L+1)> 所有a种数,直接输出0
否则(R-L+1)<= 1e5,直接枚举X的每种可能大小len,假设先把所有数都取走,再去每个包含len这种数的set中查看可以少拿多少个len这种书,求出最终拿的len的个数,对每种情况取min即可
#include<bits/stdc++.h>
using namespace std;
#define int long long
#define IO ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);
#define endl '\n'
#define all(x) (x).begin(), (x).end()
const int N = 1e5 + 10;
const int WIN = 0;
const int DRAW = 1;
const int LOSE = 2;
int m;
void solve(){
cin >> m;
vector<int>n(m);
vector<int>r(m);
vector<int>l(m);
vector<int>sum(m);
vector<vector<int>>a(m);
vector<vector<int>>c(m);
map<int,int>cnt;
map<int,vector<int>>stid;
int L = 0, R = 0;
for(int i = 0;i < m;i++){
cin >> n[i] >> l[i] >> r[i];
L += l[i];
R += r[i];
a[i].resize(n[i]);
c[i].resize(n[i]);
for(auto& e : a[i]) cin >> e, stid[e].push_back(i);
for(int j = 0;j < n[i];j++){
cin >> c[i][j];
sum[i] += c[i][j];
cnt[a[i][j]] += c[i][j];
}
}
if(R - L + 1 > cnt.size()) {
cout << "0\n";
return;
}
int ans = 1e18;
for(int len = L;len <= R;len++){
if(!cnt[len]){
cout << "0\n";
return;
}
int tmp = cnt[len];
int D = R - len;
for(auto id : stid[len]){
int p = lower_bound(all(a[id]), len) - a[id].begin();
int d = sum[id] - r[id] + (r[id] - max(l[id], r[id] - D));
int dd = min(d, c[id][p]);
tmp -= dd;
dd -= sum[id] - r[id];
D -= dd;
}
ans = min(ans, tmp);
}
cout << ans << endl;
}
signed main(){
IO;
int t = 1;
cin >> t;
while(t--) solve();
return 0;
}