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

Game

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

Problem Descriptionc++

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'.
數組

Inputui

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)
spa

Outputcode

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

Sample Inputip

1ci

Sample Outputinput

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;
}
相關文章
相關標籤/搜索