# A. Add Odd or Subtract Even

Add an odd number or subtract an even number to x each time. Ask the minimum number of operations from X to y.

Analysis: just judge the parity of x and y and discuss it.

```#include <bits/stdc++.h>
using namespace std;
int main(){
int t;
cin>>t;
while(t--){
int a,b;scanf("%d%d",&a,&b);
if(a>b){
printf("%d\n",((a&1)^(b&1))+1);
}
else if(a<b)printf("%d\n",(!((a&1)^(b&1)))+1);
else printf("0\n");
}
}```

# B. WeirdSort

Given an array A and an array p, for any i, the number of positions pi and pi + 1 of array a can be exchanged. Ask if you can make a array non descending.

Analysis: through the p array to determine a number of connecting blocks, sort each connecting block, and then determine whether the a array is in order.

```#include <bits/stdc++.h>
using namespace std;
int main(){
int t;cin>>t;
while(t--){
int n,m;cin>>n>>m;
vector<int>a(n+1),p(m+1);
for (int i = 1; i <= n; ++i) {
scanf("%d",&a[i]);
}
for (int i = 1; i <= m; ++i) {
scanf("%d",&p[i]);
}
sort(p.begin()+1,p.end());
p.erase(unique(p.begin()+1,p.end()),p.end());
int fro=p[1],bak=p[1]+1;
for (int i = 2; i <= m; ++i) {
if(p[i]!=p[i-1]+1){
sort(a.begin()+fro,a.begin()+bak+1);
fro=p[i],bak=p[i]+1;
}
else bak=p[i]+1;
}
sort(a.begin()+fro,a.begin()+bak+1);
bool ok = 1;
for (int i = 2; i <= n; ++i) {
if(a[i]<a[i-1])ok=0;
}
if(ok)puts("YES");
else puts("NO");

}
}```

# C. Perform the Combo

Given a string s and an array p, for each pi, traverse the letters of 1-pi in s, and ask how many times each letter is traversed.

Analysis: differential.

```#include <bits/stdc++.h>
using namespace std;
char s[200004];
int p[200004];
int a[200004];
int ans[26];
int main(){
int t;
cin>>t;
while(t--){
int n,m;scanf("%d%d",&n,&m);
scanf("%s",s+1);
for (int i = 0; i <= n; ++i) {
a[i]=0;
}
for (int i = 0; i < 26; ++i) {
ans[i]=0;
}
for (int i = 0; i < m; ++i) {
scanf("%d",&p[i]);
a[1]++,a[p[i]+1]--;
}
a[1]++;
int sum = 0;
for (int i = 1; i <= n; ++i) {
sum+=a[i];
ans[s[i]-'a']+=sum;
}
for (int i = 0; i < 26; ++i) {
printf("%d ",ans[i]);
}
puts("");
}
}```

# D. Three Integers

Question meaning: given three numbers ABC, you can add + 1 or - 1 to any number each time. Ask at least several times to make A < = B < = C, and A is the factor of B, and B is the factor of C.

Analysis: violent enumeration, complexity is a harmonic series.

```#include <bits/stdc++.h>

using namespace std;
int main() {
int t;
cin >> t;
while (t--) {
int a, b, c;
cin >> a >> b >> c;
int ans = 2e9,aa,bb,cc;
for (int i = 1; i <= 2e4; ++i) {
for (int j = i; j <= 2e4; j+=i) {
for (int k = j; k <= 2e4; k+=j) {
int temp = abs(a-i)+abs(b-j)+abs(c-k);
if(temp<ans){
ans = temp;
aa=i,bb=j,cc=k;
}
}
}
}
cout<<ans<<endl;
cout<<aa<<' '<<bb<<' '<<cc<<endl;
}
}```

# E. Construct the Binary Tree

Meaning: given n, D, construct a tree with n points and the sum of the depth of each store is d.

Analysis: it is easy to think that the upper bound of the sum of the depth of n points is a chain, and the lower bound is a complete binary tree.

Then you only need to calculate the number of points in each depth to get the final answer, and you can calculate the sum of a chain as (n-1) * n/2. Then you start to traverse from the deepest point, and every time you raise this point one level up, sum-1, you just need to keep putting the deepest point up to get a satisfactory answer.

```#include <bits/stdc++.h>

using namespace std;
int dep[5004];
int ans[5004];
vector<int>v[5004];
int main(){
int t;cin>>t;
while(t--){
int n,d;cin>>n>>d;
for (int i = 0; i <= n; ++i) {
v[i].clear();
}
int up = 0,dw = (n-1)*n/2;
int num = 0;
for (int i = 1; num <= n; i<<=1) {
num += i;
if(num <= n){
up += log2(i)*i;
}
else {
up += log2(i)*(i - num + n);
}
}
//        printf("%d %d\n",up,dw);
if(d < up || d > dw){
puts("NO");
continue;
}
puts("YES");
memset(dep,0, sizeof(dep));
for (int i = 0; i < n; ++i) {
dep[i]=1;
}
int now = dw,top = 1,pos = n-1;
while(now > d){
int nxt = max(pos - now + d,top);
now -= pos - nxt;
dep[pos]--;
dep[nxt]++;
pos --;

if(dep[top] == dep[top-1]*2)top++;
}
int cnt = 2;
v[0].push_back(1);
for (int i = 1; dep[i] ; ++i) {
for (int j = 1; j <= dep[i]; ++j) {
ans[cnt]=v[i-1][(j-1)/2];
v[i].push_back(cnt++);
}
}
for (int i = 2; i <= n; ++i) {
printf("%d ",ans[i]);
}
puts("");
}
}```

# F. Moving Points

Problem meaning: n points, each point has a pos and a speed, D(U,V) is the minimum distance between two points of UV, find sum D(U,V).

Analysis: for any two points, if the two attributes of one point are greater than the other, its contribution is abs(pos1-pos2).

For one-dimensional sorting, the other one-dimensional bit maintenance statistics sum contribution is enough.

```#include <bits/stdc++.h>

using namespace std;

struct BIT {
int n;
vector<long long> v;

BIT(int n) : n(n) { v.resize(n + 1); }

void update(long long x, long long d) {
while (x <= n) {
v[x] += d;
x += (x & -x);
}
}

long long que(long long x) {
long long res = 0;
while (x > 0) {
res += v[x];
x -= (x & -x);
}
return res;
}
};

BIT bit(200004),num(200004);
pair<int, int> p[200004];
unordered_map<int, int> mp;

int main() {
int n;
cin >> n;
vector<int> v;
for (int i = 1; i <= n; ++i) {
scanf("%d", &p[i].first);
}
for (int i = 1; i <= n; ++i) {
scanf("%d", &p[i].second);
v.push_back(p[i].second);
}
sort(v.begin(),v.end());
v.erase(unique(v.begin(), v.end()), v.end());
for (int i = 0; i < v.size(); ++i) {
mp[v[i]] = i + 1;
}
sort(p + 1, p + n + 1);
long long ans = 0;
for (int i = n; i >= 1; --i) {
ans += bit.que(mp[v[v.size()-1]]) -
bit.que(mp[p[i].second]-1) -
(num.que(mp[v[v.size()-1]]) - num.que(mp[p[i].second]-1))*(long long)(p[i].first - p[1].first);
bit.update(mp[p[i].second],p[i].first - p[1].first);
num.update(mp[p[i].second],1);
}
cout<<ans<<endl;
}```

176 original articles published, 527 praised, 30000 visitors+

Posted by WesPear on Wed, 26 Feb 2020 23:08:43 -0800