[unofficial solution] 2022 Niuke winter vacation algorithm basic training camp 5

Posted by hothientuan on Thu, 17 Feb 2022 14:03:24 +0100

2022 Niuke winter vacation algorithm basic training camp 5_ACM/NOI/CSP/CCPC/ICPC algorithm programming high difficulty practice competition_ Ox guest competition OJ

catalogue

A-vaccine children

B-ping Pong children

C-chess kid

D-digital children

E-resuscitation child

F-flying child

G-163 children

H-163 children

I-bunny child

J-children of the Three Kingdoms

K-dream child

A-vaccine children

Original title link: https://ac.nowcoder.com/acm/contest/23480/A

Solution idea: considering the contribution of each to the answer, it can be found that the first needle does not contribute to the improvement of hand speed, but only the second needle and the third needle contribute to the improvement of hand speed, and the contribution value is related to the interval between the first and second needles and the interval between the second and third needles respectively. You can consider enumerating the second needle, so that when the second needle is determined, the first needle and the third needle can be divided left and right, find the best position for the injection, and finally take a maximum value. The following code preprocesses all the positions where the injection can be given, and then performs dichotomy to find the best position.

AC Code:

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <cstdlib>
#include <climits>
#include <cctype>
#include <utility>

using namespace std;
typedef long long ll;
const int INF = 0x3f3f3f3f;
const int N = 1000005;
char s[N];
int pos[N];

int main(){
    //freopen("input.txt", "r", stdin);
    ios::sync_with_stdio(false);
    cin.tie(NULL);
    cout.tie(NULL);
    int n, cnt = 0;
    scanf("%d%s", &n, s + 1);
    for(int i = 1; i <= n; i++){
        if(s[i] == '0') pos[cnt++] = i;
    }
    pos[0] = -0x3f3f3f3f, pos[cnt] = 0x3f3f3f3f;
    ll k, w, q;
    scanf("%lld%lld%lld", &k, &w, &q);
    ll ans = 0;
    for(int i = 1; i <= n; i++){
        ll res = 0, t1 = 0, t2 = 0;
        if(s[i] == '0'){
            int p = lower_bound(pos, pos + cnt, i - k) - pos;
            t1 = w - abs(i - k - pos[p]) * q;
            t2 = w - abs(i - k - pos[p - 1]) * q;
            res += max(max(t1, t2), (ll)0);
            p = lower_bound(pos, pos + cnt, i + k) - pos;
            t1 = w - abs(i + k - pos[p]) * q;
            t2 = w - abs(i + k - pos[p - 1]) * q;
            res += max(max(t1, t2), (ll)0);
        }
        ans = max(ans, res);
    }
    printf("%lld\n", ans);
    return 0;
}

B-ping Pong children

Original title link: https://ac.nowcoder.com/acm/contest/23480/B

Problem solving ideas: simple (not) classified discussion can be carried out according to the requirements of the problem.

AC Code:

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <cstdlib>
#include <climits>
#include <cctype>
#include <utility>
#include <vector>

using namespace std;
typedef long long ll;
const int INF = 0x3f3f3f3f;
vector<pair<int, int> > ans;

int main(){
    //freopen("input.txt", "r", stdin);
    ios::sync_with_stdio(false);
    cin.tie(NULL);
    cout.tie(NULL);
    int t;
    scanf("%d", &t);
    while(t--){
        ans.clear();
        int x, y, flag = 0;
        scanf("%d%d", &x, &y);
        if(x < y){
            swap(x, y);
            flag = 1;
        }
        if(x < 11){
            printf("NO\n");
            continue;
        }
        int q = y;
        while(q >= 11 && (x - q + 2) % 11) q--;
        if(q >= 11){
            ans.push_back({q - 2, q});
            x -= q - 2;
            y -= q;
        }
        while(y >= 11){
            if(x % 11 == 10){
                ans.push_back({9, 11});
                x -= 9;
                y -= 10;
            }
            else{
                ans.push_back({x % 11, 11});
                x -= x % 11;
                y -= 11;
            }
        }
        if(10 * x == 11 * y){
            printf("NO\n");
            continue;
        }
        q = y;
        while((x - (q + 2)) % 11 && q + 2 >= 11) q--;
        if(q + 2 >= 11){
            ans.push_back({q + 2, q});
            x -= q + 2;
            y -= q;
        }
        if(x % 11){
            printf("NO\n");
            continue;
        }
        printf("YES\n");
        while(x){
            ans.push_back({11, y});
            y = 0;
            x -= 11;
        }
        printf("%d\n", ans.size());
        if(flag){
            for(auto i : ans){
                printf("%d %d\n", i.second, i.first);
            }
        }
        else{
            for(auto i : ans){
                printf("%d %d\n", i.first, i.second);
            }
        }
    }
    return 0;
}

C-chess kid

Original title link: https://ac.nowcoder.com/acm/contest/23480/C

Problem solving idea: because the contribution of courtesy and non courtesy to the answer is different in each game, and for different situations, the contribution of courtesy and non courtesy to the answer cannot be well judged. Therefore, it is necessary to enumerate the combination of each kind of courtesy, and finally take the maximum number of listing times of each kind. The enumeration combination here uses the method of shape pressure enumeration, that is, 1 stands for courtesy and 0 stands for no courtesy. The N-Game is abstracted into n-bit binary numbers, and enumeration isThen, for each combination, record the maximum value of each game, sort it, greedy to play the game from large to small, judge whether it is on the list after each time, and then count the answers of the current combination.

AC Code:

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <cstdlib>
#include <climits>
#include <cctype>
#include <utility>

using namespace std;
typedef long long ll;
const int INF = 0x3f3f3f3f;
const int N = 25;
int p[N], v[N], w[N], h[N];    // v [] store the maximum value of each unused courtesy
                               // w [] store the maximum value of each courtesy
                               // h [] store the maximum value of each game in each combination of courtesy
int n, k, s;

int check(int x){
    int res = 0;
    while(x){
        if(x & 1) res++;
        x >>= 1;
    }
    return res;
}

int cal(int x){
    for(int i = 0; i < n; i++){
        h[i + 1] = ((x >> i) & 1) ? w[i + 1] : v[i + 1];    // ((x > > 1) & 1) judge whether to use courtesy in scene i
    }
    sort(h + 1, h + n + 1);
    int sum = s, res = 0;
    for(int i = 1; i <= n; i++){
        sum += h[n - i + 1];
        if(sum >= p[i]) res++;
    }
    return res;
}

int main(){
    //freopen("input.txt", "r", stdin);
    ios::sync_with_stdio(false);
    cin.tie(NULL);
    cout.tie(NULL);
    cin >> n >> k >> s;
    for(int i = 1; i <= n; i++) cin >> p[i];
    for(int i = 1; i <= n; i++){
        int a, b, c, d;
        cin >> a >> b >> c >> d;
        v[i] = max(a, b);
        w[i] = max(v[i], max(c, d));
    }
    int ans = 0;
    for(int i = 0; i < (1 << n); i++){    // State pressure enumeration. 1 in binary represents courtesy
        if(check(i) == k) ans = max(ans, cal(i));
    }
    cout << ans << endl;
    return 0;
}

D-digital children

Original title link: https://ac.nowcoder.com/acm/contest/23480/D

Solution idea: search every qualified number from the single digit, and add a new number at the end of the current number every time to judge whether it meets the problem conditions. If it meets the problem conditions, continue to search, otherwise return, and then as long as the obtained number falls in the given rangeIf there is 1 in the number, it means that the number meets all conditions, and the answer can be increased by one. If it exceedsThen it means that there is no need to continue the search. Return to the next search, and finally directly output the accumulated answer of each search.

AC Code:

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <cstdlib>
#include <climits>
#include <cctype>
#include <utility>

using namespace std;
typedef long long ll;
const int INF = 0x3f3f3f3f;
ll l, r, ans;

bool isprime(ll x){
    if(x == 0 || x == 1) return false;
    for(ll i = 2; i * i <= x; i++){
        if(x % i == 0) return false;
    }
    return true;
}

void dfs(ll x, int last, int flag){
    if(x > r) return;
    if(x >= l && flag) ans++;
    for(int i = 0; i <= 9; i++){
        if(isprime(i + last)){
            dfs(x * 10 + i, i, flag || (i == 1));
        }
    }
}

int main(){
    //freopen("input.txt", "r", stdin);
    ios::sync_with_stdio(false);
    cin.tie(NULL);
    cout.tie(NULL);
    cin >> l >> r;
    for(int i = 1; i <= 9; i++){
        dfs(i, i, i == 1);
    }
    cout << ans << endl;
    return 0;
}

E-resuscitation child

Original title link: https://ac.nowcoder.com/acm/contest/23480/E

Main idea of the topic: given a string containing only 1, 2 and 3, the initial energy of the three ghosts is 1. When encountering 1 each time, ghost 1 absorbs half the energy of ghost 2 and ghost 3; When meeting 2, ghost 2 absorbs half the energy of ghost 1 and ghost 3; When encountering 3, ghost 3 absorbs half the energy of ghost 1 and ghost 2. Then there are two operations for each query. One is to modify a certain point of the string, and the other is to query the energy of the last three in a certain interval of the string.

Problem solving idea: for each case, if 1 is encountered, the change of the energy of the three is, then we can consider whether matrix multiplication can cause such a change. It can be found that as long as the matrix of the three energies is multiplied byYou can get the above changes. Similarly, a matrix can be constructed in case of 2 and 3. In this way, the segment tree can be used to maintain an energy change matrix, and then the interval merging is matrix multiplication. The answer to each question isMultiply the change matrix obtained by the query.

AC Code:

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <cstdlib>
#include <climits>
#include <cctype>
#include <utility>

#define mid (l + r >> 1)

using namespace std;
typedef long long ll;
const int INF = 0x3f3f3f3f;
const int mod = 998244353;
const int N = 100005;
char c;

ll quick_pow(ll a, ll b){
	ll res = 1;
	while(b){
		if(b & 1) res = res * a % mod;
		a = a * a % mod;
		b >>= 1;
	}
	return res;
}

ll inv(ll x){
	return quick_pow(x, mod - 2);
}

struct Matrix{    // matrix
    ll c[3][3] = {
        {0, 0, 0},
        {0, 0, 0},
        {0, 0, 0}
    };
}ans;
 
Matrix operator * (Matrix A, Matrix B){    // Matrix multiplication overload
    Matrix C;
    for(int i = 0; i < 3; i++){
        for(int j = 0; j < 3; j++){
            for(int k = 0; k < 3; k++){
                C.c[i][j] = (C.c[i][j] + A.c[i][k] * B.c[k][j] % mod) % mod;
            }
        }
    }
    return C;
}

void init(Matrix &m){
    ll t = 1 * inv(2) % mod;
    Matrix emp;
    m = emp;
    if(c == '1'){
        m.c[0][0] = 1;
        m.c[1][0] = t;
        m.c[1][1] = t;
        m.c[2][0] = t;
        m.c[2][2] = t;
    }
    if(c == '2'){
        m.c[0][0] = t;
        m.c[0][1] = t;
        m.c[1][1] = 1;
        m.c[2][1] = t;
        m.c[2][2] = t;
    }
    if(c == '3'){
        m.c[0][0] = t;
        m.c[0][2] = t;
        m.c[1][1] = t;
        m.c[1][2] = t;
        m.c[2][2] = 1;
    }
}

struct node{
    int l, r;
    Matrix val;
}tree[N << 2];

void sgt_build(int i, int l, int r){    // Build segment tree
    tree[i].l = l;
    tree[i].r = r;
    if(l == r){
        c = getchar();
        init(tree[i].val);
        return;
    }
    sgt_build(i << 1, l, mid);
    sgt_build(i << 1 | 1, mid + 1, r);
    tree[i].val = tree[i << 1].val * tree[i << 1 | 1].val;
}

void sgt_modify(int i, int x, int y){  // Single point modification
    int l = tree[i].l, r = tree[i].r;
    if(l == r){
        c = (char)y + '0';
        init(tree[i].val);
        return;
    }
    if(x <= mid) sgt_modify(i << 1, x, y);
    else sgt_modify(i << 1 | 1, x, y);
    tree[i].val = tree[i << 1].val * tree[i << 1 | 1].val;
}

void sgt_query(int i, int x, int y){   // Interval query
    int l = tree[i].l, r = tree[i].r;
    if(l >= x && r <= y){
        ans = ans * tree[i].val;
        return;
    }
    if(x <= mid) sgt_query(i << 1, x, y);
    if(y > mid) sgt_query(i << 1 | 1, x, y);
}

int main(){
    //freopen("input.txt", "r", stdin);
    ios::sync_with_stdio(false);
    cin.tie(NULL);
    cout.tie(NULL);
    int n, m;
    scanf("%d%d", &n, &m);
    getchar();
    sgt_build(1, 1, n);
    for(int i = 1; i <= m; i++){
        int op, x, y;
        scanf("%d%d%d", &op, &x, &y);
        if(op == 1){
            sgt_modify(1, x, y);
        }
        if(op == 2){
            for(int i = 0; i < 3; i++){
                for(int j = 0; j < 3; j++){
                    ans.c[i][j] = (i == j) ? 1 : 0;
                }
            }
            sgt_query(1, x, y);
            Matrix p;
            p.c[0][0] = p.c[0][1] = p.c[0][2] = 1;
            p = p * ans;
            cout << p.c[0][0] << ' ' << p.c[0][1] << ' ' << p.c[0][2] << endl;
        }
    }
    return 0;
}

F-flying child

Original title link: https://ac.nowcoder.com/acm/contest/23480/F

Problem solving idea: sort each map according to the winning rate of Jiufeng. If Jiufeng chooses the map, it must start from the far right; If you K0u1e choose a graph, you must start from the far left. Assuming that the current is the first message, the game proceeds to the x game and Jiufeng selects the y-th picture, then the number of games selected by Jiufeng in the previous x - 1 game can be judged according to the position of the sorted picture. If t game is selected, then t = n - pos + 1. So there are a total of map selection before thisSpecies; The same is true for K0u1e graph selection. Then, when the second message comes, you need to find the number of pictures selected after the last game, so you need to store the left and right endpoints of the last message. By analogy, when we get to the last piece of information, we need to consider the number of games that is less than the total number of games. There are two possibilities for the remaining number of games, either Jiufeng or K0u1e. If the remaining number of games is res, the total situation is, multiplied by the total number of schemes obtained before.

AC Code:

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <cstdlib>
#include <climits>
#include <cctype>
#include <utility>

using namespace std;
typedef long long ll;
const int INF = 0x3f3f3f3f;
const int mod = 998244353;
const int N = 100005;
ll t[N], fac[N], invfac[N];    // t[i] store the i-th map in the position after ranking the winning rate
                               // fac [] stores factorials and invfac [] stores the inverse of factorials

struct graph{    // Map information
    ll id, x, y;
    bool operator < (const graph &u) const{
        return x * u.y < u.x * y;
    }
}g[N];

struct message{    // Competition information
    ll op, x, y;
    bool operator < (const message &u) const{
        return x < u.x;
    }
}m[N];

ll quick_pow(ll a, ll b){
    ll res = 1;
    while(b){
        if(b & 1) res = res * a % mod;
        a = a * a % mod;
        b >>= 1;
    }
    return res;
}

ll C(ll a, ll b){
    return fac[a] * invfac[b] % mod * invfac[a - b] % mod;
}

void init(){
    fac[0] = invfac[0] = 1;
    for(int i = 1; i <= N; i++){
        fac[i] = fac[i - 1] * i % mod;
        invfac[i] = invfac[i - 1] * quick_pow(i, mod - 2) % mod;
    }
}

int main(){
    //freopen("input.txt", "r", stdin);
    ios::sync_with_stdio(false);
    cin.tie(NULL);
    cout.tie(NULL);
    int n, k;
    cin >> n >> k;
    init();
    for(int i = 1; i <= n; i++){
        cin >> g[i].x >> g[i].y;
        g[i].id = i;
    }
    sort(g + 1, g + n + 1);
    for(int i = 1; i <= n; i++){
        t[g[i].id] = i;
    }
    for(int i = 1; i <= k; i++) cin >> m[i].op >> m[i].x >> m[i].y;
    sort(m + 1, m + k + 1);
    int l = 0, r = n + 1;
    ll ans = 1;
    for(int i = 1; i <= k; i++){
        int lastl = l, lastr = r;
        if(m[i].op == 1){
            r = t[m[i].y];
            l += m[i].x - m[i - 1].x - (lastr - r);
            ans = ans * C(m[i].x - m[i - 1].x - 1, lastr - r - 1) % mod;
        }
        if(m[i].op == 2){
            l = t[m[i].y];
            r -= m[i].x - m[i - 1].x - (l - lastl);
            ans = ans * C(m[i].x - m[i - 1].x - 1, l - lastl - 1) % mod;
        }
    }
    ans = ans * quick_pow(2, r - l - 1) % mod;
    cout << ans << endl;
    return 0;
}

G-163 children

Original title link: https://ac.nowcoder.com/acm/contest/23480/G

Solution idea: just give the answer on your compiler (of course, you can also use permutation and combination to calculate the answer).

Violence Code:

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <cstdlib>
#include <climits>
#include <cctype>
#include <utility>

using namespace std;
typedef long long ll;
const int INF = 0x3f3f3f3f;

bool check(int i, int j, int k, int x, int y, int z){
	if(i == j && i == k && i == x && i == y) return true;
	if(i == j && i == k && i == x && i == z) return true;
	if(i == j && i == k && i == y && i == z) return true;
	if(i == j && i == x && i == y && i == z) return true;
	if(i == k && i == x && i == y && i == z) return true;
	if(j == k && j == x && j == y && j == z) return true;
	return false;
}

int main(){
    //freopen("input.txt", "r", stdin);
    ios::sync_with_stdio(false);
    cin.tie(NULL);
    cout.tie(NULL);
    int cnt = 0;
    for(int i = 1; i <= 13; i++){
    	for(int j = i; j <= 13; j++){
    		for(int k = j; k <= 13; k++){
    			for(int x = k; x <= 13; x++){
    				for(int y = x; y <= 13; y++){
    					for(int z = y; z <= 13; z++){
    						if(check(i, j, k, x, y, z)) continue;
							cnt++;
						}
					}
				}
			}
		}
	}
	cout << cnt << endl;
    return 0;
}

Final answer: 18395

H-163 children

Original title link: https://ac.nowcoder.com/acm/contest/23480/H

Problem solving idea: fooling around with problems, don't want to make up OvO

AC Code:

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <cstdlib>
#include <climits>
#include <cctype>
#include <utility>
#include <vector>

using namespace std;
typedef long long ll;
const int INF = 0x3f3f3f3f;
vector<int> p[14][14][14];
vector<string> s[14][14][14];

string CHG(int x){
    if(x==1) return "A";
    if(x==10) return "T";
    if(x==11) return "J";
    if(x==12) return "Q";
    if(x==13) return "K";
    return to_string(x);
}

void solve(){
    vector<int> a(6);
    for(int i = 0; i < 6; i++){
        char c;
        while(c = getchar()){
            if(c == 'A' || c == 'J' || c == 'Q' || c == 'K' || c == 'T' || c >= '2' && c <= '9') break;
        }
        if(c == 'T') a[i] = 10;
        else if(c == 'A') a[i] = 1;
        else if(c == 'J') a[i] = 11;
        else if(c == 'Q') a[i] = 12;
        else if(c == 'K') a[i] = 13;
        else a[i] = c - '0';
    }
    for(int i = 1; i <= 10; i++){
        random_shuffle(a.begin(), a.end());
        for(int j = 0; j < 13; j++)
            for(int k = 0; k < 13; k++){
                int x = p[a[0]][a[1]][a[2]][j];
                int y = p[a[3]][a[4]][a[5]][k];
                if(x + y == 163){
                    cout << s[a[0]][a[1]][a[2]][j] << '+' << s[a[3]][a[4]][a[5]][k] << endl;
                    return;
                }
                if(y - x == 163){
                    cout << s[a[3]][a[4]][a[5]][k] << '-' << s[a[0]][a[1]][a[2]][j] << endl;
                    return;
                }
                if(x - y == 163){
                    cout << s[a[0]][a[1]][a[2]][j] << '-' << s[a[3]][a[4]][a[5]][k] << endl;
                    return;
                }
                if(x * y == 163){
                    cout << s[a[0]][a[1]][a[2]][j] << '*' << s[a[3]][a[4]][a[5]][k] << endl;
                    return;
                }
            }
    }
    cout << "OvO" << endl;
}

int main(){
    for(int i = 1; i <= 13; i++)
        for(int j = 1; j <= 13; j++)
            for(int k = 1; k <= 13; k++){
                p[i][j][k].emplace_back(i + j + k); s[i][j][k].emplace_back("(" + CHG(i) + "+" + CHG(j) + "+" + CHG(k) + ")");
                p[i][j][k].emplace_back(i + j - k); s[i][j][k].emplace_back("(" + CHG(i) + "+" + CHG(j) + "-" + CHG(k) + ")");
                p[i][j][k].emplace_back(i + j * k); s[i][j][k].emplace_back("(" + CHG(i) + "+" + CHG(j) + "*" + CHG(k) + ")");
                p[i][j][k].emplace_back(i - j + k); s[i][j][k].emplace_back("(" + CHG(i) + "-" + CHG(j) + "+" + CHG(k) + ")");
                p[i][j][k].emplace_back(i - j - k); s[i][j][k].emplace_back("(" + CHG(i) + "-" + CHG(j) + "-" + CHG(k) + ")");
                p[i][j][k].emplace_back(i - j * k); s[i][j][k].emplace_back("(" + CHG(i) + "-" + CHG(j) + "*" + CHG(k) + ")");
                p[i][j][k].emplace_back(i * j + k); s[i][j][k].emplace_back("(" + CHG(i) + "*" + CHG(j) + "+" + CHG(k) + ")");
                p[i][j][k].emplace_back(i * j - k); s[i][j][k].emplace_back("(" + CHG(i) + "*" + CHG(j) + "-" + CHG(k) + ")");
                p[i][j][k].emplace_back(i * j * k); s[i][j][k].emplace_back("(" + CHG(i) + "*" + CHG(j) + "*" + CHG(k) + ")");
                p[i][j][k].emplace_back((i + j) * k); s[i][j][k].emplace_back("((" + CHG(i) + "+" + CHG(j) + ")" + "*" + CHG(k) + ")");
                p[i][j][k].emplace_back((i - j) * k); s[i][j][k].emplace_back("((" + CHG(i) + "-" + CHG(j) + ")" + "*" + CHG(k) + ")");
                p[i][j][k].emplace_back(i * (j + k)); s[i][j][k].emplace_back("(" + CHG(i) + "*" + "(" + CHG(j) + "+" + CHG(k) + "))");
                p[i][j][k].emplace_back(i * (j - k)); s[i][j][k].emplace_back("(" + CHG(i) + "*" + "(" + CHG(j) + "-" + CHG(k) + "))");
            }
    int t;
    cin >> t;
    while(t--){
        solve();
    }
    return 0;
}

I-bunny child

Original title link: https://ac.nowcoder.com/acm/contest/23480/I

Problem solving idea: since it takes K minutes to fall asleep each time, it is necessary to deal with the interval time of every two words in order to judge whether you fall asleep during this period. Sort the interval time, ask for two points each time, find the first interval greater than k time, add and subtract the interval time after this point. These sleep times are the total sleep time, which can be processed with prefix and, Every inquiryFind,calculation.

AC Code:

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <cstdlib>
#include <climits>
#include <cctype>
#include <utility>

using namespace std;
typedef long long ll;
const int INF = 0x3f3f3f3f;
const int N = 1000005;
ll t[N], dif[N], sum[N];
int n, q;

void init(){
    for(int i = 1; i < n; i++){
        dif[i] = t[i + 1] - t[i];
    }
    sort(dif + 1, dif + n);
    for(int i = 1; i < n; i++){
        sum[i] = sum[i - 1] + dif[i];
    }
}

int main(){
    //freopen("input.txt", "r", stdin);
    ios::sync_with_stdio(false);
    cin.tie(NULL);
    cout.tie(NULL);
    scanf("%d%d", &n, &q);
    for(int i = 1; i <= n; i++) scanf("%lld", &t[i]);
    init();
    while(q--){
        ll k, p, ans = 0;
        scanf("%lld%lld", &k, &p);
        int pos = upper_bound(dif + 1, dif + n, k) - dif;
        ans = sum[n - 1] - sum[pos - 1] - k * (n - pos);
        if(ans >= p) puts("Yes");
        else puts("No");
    }
    return 0;
}

J-children of the Three Kingdoms

Original title link: https://ac.nowcoder.com/acm/contest/23480/J

Solution: in order to survive, whether I kill or duel, the other party must play a card (which can be flash, peach and duel). Therefore, without knowing the hand, the condition for the other party to survive is that the number of his hand is greater than or equal to the number of our kill and duel, otherwise the opponent will lose.

AC Code:

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <cstdlib>
#include <climits>
#include <cctype>
#include <utility>

using namespace std;
typedef long long ll;
const int INF = 0x3f3f3f3f;

int main(){
    //freopen("input.txt", "r", stdin);
    ios::sync_with_stdio(false);
    cin.tie(NULL);
    cout.tie(NULL);
    ll n, m, k;
    cin >> n >> m >> k;
    if(k >= n + m) cout << "NO" << endl;
    else cout << "YES" << endl;
    return 0;
}

K-dream child

Original title link: https://ac.nowcoder.com/acm/contest/23480/K

Problem solving idea: for the single point operation of water magic explosion skill, you can directly use the tree array to store the damage value; For the skill of xuanbing array, multiple single point operations can also be regarded as several single point operations if len is large, which is the same as the water magic explosion operation; If len is small and the operation is intensive, it is not easy to operate directly. At this time, block operation is required. rememberIt indicates the amount of damage with the length of i of the block with the leftmost end point j. note that the position x is not damaged, so special judgment is required, or the damage reduction operation is directly carried out on point x alone. For queries, those queries with single point operation can be directly completed with the prefix and query of tree array; For block queries, enumerate len. For X, the contribution of the whole block is x / len + 1, and the contribution of the whole block is x / len. Let k = x% len, then the contribution of the prefix sum is.

AC Code:

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <cstdlib>
#include <climits>
#include <cctype>
#include <utility>

#define lowbit(x) (x & -x)

using namespace std;
typedef long long ll;
const int INF = 0x3f3f3f3f;
const int N = 100005, M = 500;
ll tree[N];
ll block[M + 5][M + 5];
int n, m;

void add(int x, int y){
    while(x <= n){
        tree[x] += y;
        x += lowbit(x);
    }
}

ll ask(int x){
    ll res = 0;
    while(x > 0){
        res += tree[x];
        x -= lowbit(x);
    }
    return res;
}

ll query(int x){
    ll res = 0;
    for(int i = 1; i <= M; i++){
        if(x % i == 0) res += block[i][i] * (x / i);
        else res += block[i][x % i] * (x / i + 1) + (block[i][i] - block[i][x % i]) * (x / i);
    }
    return res;
}

int main(){
    //freopen("input.txt", "r", stdin);
    ios::sync_with_stdio(false);
    cin.tie(NULL);
    cout.tie(NULL);
    cin >> n >> m;
    while(m--){
        int op, x, y, len, l, r;
        cin >> op;
        if(op == 1){
            cin >> x >> y;
            add(x, y);
        }
        if(op == 2){
            cin >> x >> y >> len;
            if(len > M){
                for(int i = x % len == 0 ? len : x % len; i <= n; i += len){
                    add(i, y);
                }
            }
            else{
                for(int i = x % len == 0 ? len : x % len; i <= len; i++){
                    block[len][i] += y;
                }
            }
            add(x, -y);
        }
        if(op == 3){
            cin >> l >> r;
            cout << query(r) - query(l - 1) + ask(r) - ask(l - 1) << endl;
        }
    }
    return 0;
}

Topics: C++ Algorithm ICPC