2018 Multi-University Training Contest 2(部分题解)

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/m0_37444209/article/details/81843577

Game

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 1770    Accepted Submission(s): 1089

Problem Description

Alice and Bob are playing a game.
The game is played on a set of positive integers from 1 to n.
In one step, the player can choose a positive integer from the set, and erase all of its divisors from the set. If a divisor doesn't exist it will be ignored.
Alice and Bob choose in turn, the one who cannot choose (current set is empty) loses.
Alice goes first, she wanna know whether she can win. Please judge by outputing 'Yes' or 'No'.

Input

There might be multiple test cases, no more than 10. You need to read till the end of input.
For each test case, a line containing an integer n. (1≤n≤500)

Output

A line for each test case, 'Yes' or 'No'.

Sample Input

1

Sample Output

Yes

题意:A和B在一串数字上操作,数字范围为1-n, 每次只能取一个数及其它的所有因子,那个先不能操作,那个先输;

题解:如果存在B胜的状态,那么A也能到达,所以本题对于A来说只有必胜态。

#include<bits/stdc++.h>
#define ios1 ios::sync_with_stdio(0)
#define ios2 cin.tie(0)
#define LL long long
#define INF 0x3f3f3f3f
using namespace std;

int main() {
	int n;
	while(scanf("%d", &n) == 1) {
		printf("Yes\n");
	}
	return 0;
}

Naive Operations

Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 502768/502768 K (Java/Others)
Total Submission(s): 1899    Accepted Submission(s): 258

Problem Description

In a galaxy far, far away, there are two integer sequence a and b of length n.
b is a static permutation of 1 to n. Initially a is filled with zeroes.
There are two kind of operations:
1. add l r: add one for al,al+1...ar
2. query l r: query ∑ri=lai/bi

Input

There are multiple test cases, please read till the end of input file.
For each test case, in the first line, two integers n,q, representing the length of a,b and the number of queries.
In the second line, n integers separated by spaces, representing permutation b.
In the following q lines, each line is either in the form 'add l r' or 'query l r', representing an operation.
1≤n,q≤100000, 1≤lrn, there're no more than 5 test cases.

Output

Output the answer for each 'query', each one line.

Sample Input

5 12

1 5 2 4 3

add 1 4

query 1 4

add 2 5

query 2 5

add 3 5

query 1 5

add 2 4

query 1 4

add 2 5

query 2 5

add 2 2

query 1 5

Sample Output

1

1

2

4

4

6

题意:n个数,2种操作,2个数组,a数组初始都为0,然后给了b数组的值,

add 是给l到r都加1,query是查询l到r的

∑ri=⌊ai/bi⌋的和.

思路:我们只需维护b数组的区间最小值就可以了,由于这个是向下取整,因此只有当bi减为0的时候才会对所求的区间有贡献值,所以对a数组的加1的操作,相当于对b数组的减1的操作.

如果区间的最小值min>1,那么min--,否则向下查找;  min>1的子区间继续之前的操作,min==1的让贡献值加1,所属的值变为本来的值

/**
add a b c:把区间[a,b]内的所有数都增加 c
sum a b:查询区间[a,b]的区间和
min a b:查询区间[a,b]的最小值
*/
#include <bits/stdc++.h>
using namespace std;
const int maxn = 1e5 + 10;
const long long INF = 1LL << 62;
struct Segment_tree {
    struct Node {
        int l, r;///左右区间
        int sum, min, add_lazy;///贡献值, 区间最小值, 标记
    } tre[maxn << 2];
    int arr[maxn];
    inline void push_up(int rt) {
        if(tre[rt].l == tre[rt].r) {
            return ;
        }
        tre[rt].sum = tre[rt<<1].sum + tre[rt<<1|1].sum;
        tre[rt].min = min(tre[rt<<1].min, tre[rt<<1|1].min);
    }
    inline void push_down(int rt) {
        if(tre[rt].add_lazy) {
            tre[rt<<1].add_lazy += tre[rt].add_lazy;
            tre[rt<<1].min -= tre[rt].add_lazy;
            tre[rt<<1|1].add_lazy += tre[rt].add_lazy;
            tre[rt<<1|1].min -= tre[rt].add_lazy;
            tre[rt].add_lazy = 0;
        }
    }
    void build(int rt,int l,int r) {
        tre[rt].l = l;
        tre[rt].r = r;
        tre[rt].add_lazy = 0;
        if(l == r) {
            tre[rt].sum = 0;
            tre[rt].min = arr[l];
            return ;
        }
        int mid = (l + r) >> 1;
        build(rt<<1,l,mid);
        build(rt<<1|1,mid+1,r);
        push_up(rt);
    }
    void update1(int rt,int l,int r) { ///add
        push_down(rt);
        if(l == tre[rt].l && tre[rt].r == r && tre[rt].min > 1) {
            tre[rt].add_lazy += 1;
            tre[rt].min -= 1;
            return ;
        }
        if(tre[rt].l == tre[rt].r) {
            tre[rt].add_lazy += 1;
            tre[rt].min -= 1;
            if(tre[rt].min <= 0) {
                tre[rt].min = arr[l];
                tre[rt].sum += 1;
            }
            return ;
        }
        int mid = (tre[rt].l + tre[rt].r) >> 1;
        if(r <= mid) {
            update1(rt<<1,l,r);
        } else if(l > mid) {
            update1(rt<<1|1,l,r);
        } else {
            update1(rt<<1,l,mid);
            update1(rt<<1|1,mid+1,r);
        }
        push_up(rt);
    }
    int query1(int rt,int l,int r) { ///sum
        push_down(rt);
        if(l == tre[rt].l && tre[rt].r == r) {
            return tre[rt].sum;
        }
        int mid = (tre[rt].l + tre[rt].r) >> 1;
        if(r <= mid) {
            return query1(rt<<1,l,r);
        } else if(l > mid) {
            return query1(rt<<1|1,l,r);
        } else {
            return query1(rt<<1,l,mid) + query1(rt<<1|1,mid+1,r);
        }
    }
} S;

int main() {
    int n, q;
    while(cin >> n >> q) {
        for(int i = 1; i <= n; i++) {
            scanf("%d", &S.arr[i]);
        }
        S.build(1, 1, n);
        string s;
        int l, r;
        while(q--) {
            cin >> s >> l >> r;
            if(s == "add") {
                S.update1(1, l, r);
            }
            else {
                cout << S.query1(1, l, r) << endl;
            }
        }
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/m0_37444209/article/details/81843577