打昆明打傻了,不会写题了QWQ

​A - Red Versus Blue​

要求连续的Codeforces Round #782 (Div. 2) ABCD_#define的数量最少,也就是用Codeforces Round #782 (Div. 2) ABCD_算法_02尽可能的将Codeforces Round #782 (Div. 2) ABCD_#define隔开,显然Codeforces Round #782 (Div. 2) ABCD_#define_04Codeforces Round #782 (Div. 2) ABCD_算法_02最多分成Codeforces Round #782 (Div. 2) ABCD_数位_06段,那么直接将Codeforces Round #782 (Div. 2) ABCD_#define平均分配到每一段即可。

#include <bits/stdc++.h>
#define int long long
#define endl '\n'
using namespace std;

const int N = 1e5 + 10;
int a[N];

inline void solve(){
int n, r, b; cin >> n >> r >> b;
int avg = r / (b + 1), det = r % (b + 1);

for (int i = 1; i <= b + 1; i++) a[i] = avg;
for (int i = 1; i <= det; i++) a[i]++;

for (int i = 1; i <= b + 1; i++) {
for (int j = 1; j <= a[i]; j++) cout << "R";
if (i < b + 1) cout << "B";
}
cout << endl;

}

signed main(){
int t = 0; cin >> t;
while(t--) solve();
return 0;
}

​B - Bit Flipping​

给定Codeforces Round #782 (Div. 2) ABCD_i++_08序列,每次可以选定一个数位,翻转除该数位以外的所有数位。求Codeforces Round #782 (Div. 2) ABCD_算法_09翻转后得到的字典序最大的字符串。

Codeforces Round #782 (Div. 2) ABCD_算法_09的奇偶性对答案的影响讨论即可。将余数全部算在最后一个数字上。

#include <bits/stdc++.h>
#define int long long
#define endl '\n'
using namespace std;

const int N = 1e5 + 100;
int ans[N];

inline void solve(){
int n, k = 0; string s; cin >> n >> k >> s;
memset(ans, 0, (n + 10) * sizeof(int));
int kk = k;
for (int i = 0; i < n && kk > 0; i++)
if (k % 2 == s[i] - '0') ans[i] = 1, kk--;

ans[n - 1] += kk;
for (int i = 0; i < n; i++)
if ((k - ans[i]) % 2 == 1) s[i] = '1' - (s[i] - '0');
cout << s << endl;
for(int i = 1; i <= n; i++){
cout << ans[i] << " \n";
}
}

signed main(){
int t = 0; cin >> t;
while(t--) solve();
return 0;
}

​C - Line Empire​

起始状态下的首都位于Codeforces Round #782 (Div. 2) ABCD_数位_11,每次可以:

  • 首都Codeforces Round #782 (Div. 2) ABCD_数位_12,选择攻占一个城市Codeforces Round #782 (Div. 2) ABCD_算法_13,花费为Codeforces Round #782 (Div. 2) ABCD_i++_14,攻占城市要求首都和城市间没有未被攻占的城市;
  • 将首都Codeforces Round #782 (Div. 2) ABCD_数位_12变成为某个已经被攻占的城市Codeforces Round #782 (Div. 2) ABCD_算法_13,花费为Codeforces Round #782 (Div. 2) ABCD_#define_17

求攻占全部城市的最小花费。

我们先求出首都位于Codeforces Round #782 (Div. 2) ABCD_算法_18时的总花费:
Codeforces Round #782 (Div. 2) ABCD_#define_19
合并一下可以得到:
Codeforces Round #782 (Div. 2) ABCD_算法_20
类似的,我们可以得到Codeforces Round #782 (Div. 2) ABCD_i++_21时的花费:
Codeforces Round #782 (Div. 2) ABCD_算法_22
作差可得:
Codeforces Round #782 (Div. 2) ABCD_c++_23
观察到未征服的城市具有单调性,我们可以二分使得Codeforces Round #782 (Div. 2) ABCD_#define_24,即为最优位置。

#include <bits/stdc++.h>
#define int long long
#define endl '\n'
using namespace std;

const int N = 4e5 + 10;
int x[N];

inline void solve(){
int n = 0, a = 0, b = 0; cin >> n >> a >> b;
for(int i = 1; i <= n; i++) cin >> x[i];
int l = 0, r = n;
while(l < r){
int mid = l + r >> 1;
if((a + b) - (n - mid) * b < 0) l = mid + 1;
else r = mid;
}
int ans = x[l] * (a + b);
for(int i = l + 1; i <= n; i++) ans += b * (x[i] - x[l]);
cout << ans << endl;

}

signed main(){
int t = 0; cin >> t;
while(t--) solve();
return 0;
}

​D - Reverse Sort Sum​

定义数组Codeforces Round #782 (Div. 2) ABCD_c++_25为一个Codeforces Round #782 (Div. 2) ABCD_i++_08数组。定义函数Codeforces Round #782 (Div. 2) ABCD_数位_27为对数组Codeforces Round #782 (Div. 2) ABCD_c++_25Codeforces Round #782 (Div. 2) ABCD_算法_29项排序后的结果。定义数组Codeforces Round #782 (Div. 2) ABCD_算法_02的计算方式由函数导出,即Codeforces Round #782 (Div. 2) ABCD_i++_31,定义数组Codeforces Round #782 (Div. 2) ABCD_算法_32Codeforces Round #782 (Div. 2) ABCD_算法_33,现在给定数组Codeforces Round #782 (Div. 2) ABCD_算法_32的值,要求你求出数组Codeforces Round #782 (Div. 2) ABCD_c++_25(Codeforces Round #782 (Div. 2) ABCD_i++_08数组)。

首先容易证明,每个Codeforces Round #782 (Div. 2) ABCD_数位_37被加了Codeforces Round #782 (Div. 2) ABCD_i++_38次,因此可以通过Codeforces Round #782 (Div. 2) ABCD_#define_39得到Codeforces Round #782 (Div. 2) ABCD_数位_37的数目。然后我们考虑倒序还原序列。我们发现对于某个位置Codeforces Round #782 (Div. 2) ABCD_c++_41,如果加和Codeforces Round #782 (Div. 2) ABCD_算法_42,那么该位置一定是Codeforces Round #782 (Div. 2) ABCD_数位_37

同时,对于位置Codeforces Round #782 (Div. 2) ABCD_c++_41而言,如果当前有Codeforces Round #782 (Div. 2) ABCD_数位_45Codeforces Round #782 (Div. 2) ABCD_数位_37,那么在Codeforces Round #782 (Div. 2) ABCD_算法_47时这Codeforces Round #782 (Div. 2) ABCD_数位_45Codeforces Round #782 (Div. 2) ABCD_数位_37会对Codeforces Round #782 (Div. 2) ABCD_数位_50区间造成区间Codeforces Round #782 (Div. 2) ABCD_i++_51的贡献,我们在倒序遍历的时候还原这个过程(即反过来对区间Codeforces Round #782 (Div. 2) ABCD_算法_52)即可。

这里区间和由于比较简单,可以用树状数组、甚至普通数组维护。偷懒直接拉了个线段树板子过了。

#include <bits/stdc++.h>
#define int long long
#define endl '\n'
using namespace std;

const int N = 2e5 + 10;
int a[N], c[N];

#define lson rt << 1, l,
#define rson rt << 1 | 1, mid + 1,
#define ls rt << 1
#define rs rt << 1 | 1

int len, q, tree[N << 2], lazy[N << 2];

namespace SegmentTree{
const int N = 1e5 + 10;
inline void push_up(int rt) { tree[rt] = tree[ls] + tree[rs]; }

inline void push_down(int rt, int m){
if(!lazy[rt]) return;
lazy[ls] += lazy[rt], lazy[rs] += lazy[rt];
tree[ls] += lazy[rt] * (m - (m >> 1));
tree[rs] += lazy[rt] * (m >> 1);
lazy[rt] = 0;
}

static void build(int rt, int l, int r){
tree[rt] = lazy[rt] = 0;
if(l == r){
tree[rt] = c[l];
return;
}
int mid = l + r >> 1;
build(lson), build(rson);
push_up(rt);
}

static void update_part(int rt, int l, int r, int L, int R, int val){
if(l >= L && r <= R){
lazy[rt] += val, tree[rt] += (r - l + 1) * val;
return;
}
int mid = l + r >> 1;
push_down(rt, r - l + 1);
if(mid >= L) update_part(lson, L, R, val);
if(mid < R) update_part(rson, L, R, val);
push_up(rt);
}

static void update_point(int rt, int l, int r, int pos, int val){
if(l == r){
tree[rt] += val;
return;
}
int mid = l + r >> 1;
if(mid >= pos) update_point(lson, pos, val);
else update_point(rson, pos, val);
push_up(rt);
}

static int query(int rt, int l, int r, int L, int R){
if(l >= L && r <= R) return tree[rt];
int mid = l + r >> 1, ans = 0;
push_down(rt, r - l + 1);
if(mid >= L) ans += query(lson, L, R);
if(mid < R) ans += query(rson, L, R);
return ans;
}
}

inline void solve(){
int n = 0, sum = 0; cin >> n;
memset(a, 0, (n + 10) * sizeof(int));
for(int i = 1; i <= n; i++) cin >> c[i], sum += c[i];
int cnt1 = sum / n; SegmentTree::build(1, 1, n);
for(int i = n; i >= 1; i--){
if(SegmentTree::query(1, 1, n, i, i) >= i){
a[i] = 1;
SegmentTree::update_part(1, 1, n, i - cnt1 + 1, i, -1);
cnt1--;
}
}
for(int i = 1; i <= n; i++) cout << a[i] << " \n"[i == n];
}

signed main(){
int t = 0; cin >> t;
while(t--) solve();
return 0;
}