2019 cattle off more school Game 9

2019 cattle off more school Game 9

A. The power of Fibonacci

Seeking Fibonacci number of \ (m \) before the power of the \ (n-\) value of the item and the mold 1e9

\((1<=n<=1e9, 1<=m<=1000)\)

We must first know the next Fibonacci column mode meaning there is a festival of cycling, its circulation section must have been its \ (m \) cycle of the power section

Then \ (1E9 \) split into \ (^ 2 ^ 5 9 * 9 \) of \ (2 ^ 9 \) and \ (5 ^ 9 \) both modulus of each cycle to find the section, \ (2 9 ^ \) circulation section 768, \ (5 ^ 9 \) of the festival is 7,812,500 cycles

The two were then put together a determined you can get the answer

ps: Why fast every time the power of the modulus ( \ (2 ^ 9 \) or \ (5 ^ 9 \) ) pass in time is directly modulus nailed three times 1e9, ah ...

#include <bits/stdc++.h>
using namespace std;

const int N = 8e6 + 10;
const int mod[2] = {512, 125 * 125 * 125};

int f[N];
int ans[2];
int n, m;

int qp(int a, int n, int mod = 1000000000) {
    int res = 1;
    while(n) {
        if(n & 1)
            res = 1LL * res * a % mod;
        a = 1LL * a * a % mod;
        n >>= 1;
    }
    return res;
}

int main() {
    scanf("%d%d", &n, &m);
    for(int k = 0; k < 2; ++k) {
        f[0] = 0; f[1] = 1;
        int j = 2;
        for(; ; ++j) {
            f[j] = f[j - 1] + f[j - 2];
            if(f[j] >= mod[k]) f[j] -= mod[k];
            if(f[j] == 0 && f[j - 1] == 1) break;
        }
        for(int i = 0; i < j; ++i) {
            int cnt = n / j + (n % j >= i);
            ans[k] = (ans[k] + 1LL * cnt * qp(f[i], m)) % mod[k];
        }
    }
    while(ans[1] % mod[0] != ans[0]) ans[1] += mod[1];
    printf("%d\n", ans[1]);
    return 0;
}

B. Quadratic equation

solved at 00:53

His teammates do, quadratic residue, will not

D. Knapsack Cryptosystem

solved at 00:20

\ (n-\) th items, each item has a weight that you want to find a subset of the article such that the weight and exactly \ (S \) \ ((. 1 <= n-<= 36) \) has a unique solution to ensure that the input

Binary search, first consider the first half, the binary-like pressure all cases they can be composed of all thrown \ (map \) to go, then consider half after every pressure binary form and then go to \ (map \) in search of solution

#include <bits/stdc++.h>
using namespace std;

int n, p, q;
long long s, a[40];
int to[(1 << 18) + 10];

map<long long, int> pp;

void init() {
    int msk = 2;
    to[1] = 0;
    for(int i = 1; i <= 17; ++i) {
        to[msk] = i;
        msk *= 2;
    }
}

void print(int maskp, int maskq) {
    for(int i = 0; i < p; ++i) 
        printf("%d", 1 & (maskp >> i));
    for(int i = 0; i < q; ++i)
        printf("%d", 1 & (maskq >> i));
    puts("");
}

int main() {
    init();
    cin >> n >> s;
    for(int i = 0; i < n; ++i)
        cin >> a[i];
    p = n / 2;
    q = n - p;
    for(int i = 0; i < (1 << p); ++i) {
        long long tmp = 0;
        for(int j = i; j; j -= j & -j)
            tmp += a[to[j & -j]];
        pp[tmp] = i;
    }
    for(int i = 0; i < (1 << q); ++i) {
        long long tmp = 0;
        for(int j = i; j; j -= j & -j) 
            tmp += a[to[j & -j] + p];
        auto it = pp.lower_bound(s - tmp);
        if(it->first + tmp == s) {
            print(it->second, i);
            return 0;
        }
    }
    puts("-1");
    return 0;
}

E. All men are brothers

solved at 00:49

\ (n-\) individual, a start not know each other, \ (m \) operations, each two people will know each other, having this knowledge transfer and symmetry relations, after each operation to select the required output \ (4 \) individuals do not know each other a number of programs

Disjoint-set to maintain communication block size

Consider merging two connected blocks, then the answer would be a reduction in some of the answers than to reduce the communication is two blocks each pick one, then select the number of programs is not the same in the two communication block from the outside, not specific write, look at the code (sz all communication means and the square of the block size)

#include <bits/stdc++.h>
using namespace std;

const int N = 1e5 + 10;

int n, m, x, y;
int fa[N], size[N];
long long sz;
unsigned long long ans;

int find(int x) {
    return fa[x] == x ? x : find(fa[x]);
}

void unite(int x, int y) {
    int fx = find(x), fy = find(y);
    if(fx != fy) {
        if(size[fx] < size[fy])
            swap(fx, fy);
        fa[fy] = fx;
        size[fx] += size[fy];
    }
}

int main() {
    scanf("%d%d", &n, &m);
    if(n <= 3) {
        for(int i = 0; i <= m; ++i)
            puts("0");
        return 0;
    }
    for(int i = 1; i <= n; ++i) {
        fa[i] = i;
        size[i] = 1;
    }
    ans = 1ULL * n * (n - 1) / 2 * (n - 2) / 3 * (n - 3) / 4;
    printf("%llu\n", ans);
    sz = n;
    for(int i = 1; i <= m; ++i) {
        scanf("%d%d", &x, &y);
        if(find(x) == find(y)) {
            printf("%llu\n", ans);
            continue;
        }
        int sx = size[find(x)], sy = size[find(y)];
        ans -= 1ULL * sx * sy * (1ULL * (n - sx - sy) * (n - sx - sy) - (sz - 1LL * sx * sx - 1LL * sy * sy)) / 2;
        sz -= 1LL * sx * sx;
        sz -= 1LL * sy * sy;
        sz += 1LL * (sx + sy) * (sx + sy);
        printf("%llu\n", ans);
        unite(find(x), find(y));
    }
    return 0;
}

H. Cutting Bamboos

solved at 03:11(+2)

There \ (n-\) strain bamboo, per plant height, \ (Q \) times query, a query each time interval \ (L, R & lt \) , given \ (x, y \)

, The horizontal direction refers to a cut \ (Y \) knife and the same amount of each bamboo down across the board and the final cutting height \ (0 \) , seeking the first \ (X \) blade height

First, the same total amount of each down across the board, it can be determined on \ (X \) knife to the second \ (Y \) to the total amount of the cut, and then half the answer, the query in the total height of the bamboo current (less blade is the height of the bamboo itself, is greater than the height of the blade), it is equivalent to seeking intervals of less than \ (K \) number and the number thereof and may be implemented by President tree overall complexity \ (O ( Q \ log (n-) (\ log (H) + 50)) \) (binary floating-point number is 50, may not need as much)

#include <bits/stdc++.h>
using namespace std;

const int N = 2e5 + 10;

struct node {
    int l, r, cnt;
    long long sum;
}Tree[N * 20];
int root[N];

int cnt;

void init() {
    cnt = 0;
    root[0] = 0;
    Tree[0].l = Tree[0].r = Tree[0].cnt = Tree[0].sum = 0;
}

void update(int &rt, int l, int r, int num) {
    Tree[++cnt] = Tree[rt];
    rt = cnt;
    Tree[rt].cnt++;
    Tree[rt].sum += num;
    if(l == r)
        return;
    int mid = l + r >> 1;
    if(num <= mid)
        update(Tree[rt].l, l, mid, num);
    else
        update(Tree[rt].r, mid + 1, r, num);
}

pair<int, long long> query(int i, int j, int num, int l, int r) {
    if(l == r)
        return make_pair(Tree[j].cnt - Tree[i].cnt, Tree[j].sum - Tree[i].sum);
    int mid = l + r >> 1;
    if(num <= mid) 
        return query(Tree[i].l, Tree[j].l, num, l, mid);
    pair<int, long long> tmp = query(Tree[i].r, Tree[j].r, num, mid + 1, r);
    return make_pair(Tree[Tree[j].l].cnt - Tree[Tree[i].l].cnt + tmp.first, Tree[Tree[j].l].sum - Tree[Tree[i].l].sum + tmp.second);
}

int n, q, l, r, x, y;
int h[N];
long long sumh[N];

double check(double height) {
    if(height < 1) 
        return (r - l + 1) * height;
    int c; long long s;
    tie(c, s) = query(root[l - 1], root[r], (int)height, 1, 100000);
    return s + (r - l + 1 - c) * height;
}

int main() {
    init();
    scanf("%d%d", &n, &q);
    for(int i = 1; i <= n; ++i) {
        scanf("%d", &h[i]);
        root[i] = root[i - 1];
        update(root[i], 1, 100000, h[i]);
        sumh[i] = sumh[i - 1] + h[i];
    }
    while(q--) {
        scanf("%d%d%d%d", &l, &r, &x, &y);
        int ll = 0, rr = 1e5, ans;
        double tar = (1.0 * y - x) / y * (sumh[r] - sumh[l - 1]);
        while(ll <= rr) {
            int mid = ll + rr >> 1;
            if(check(mid) <= tar) {
                ans = mid;
                ll = mid + 1;
            }
            else {
                rr = mid - 1;
            }
        }
        double o, lll = ans, rrr = ans + 1;
        for(int _ = 0; _ <= 50; ++_) {
            o = (lll + rrr) / 2;
            if(check(o) <= tar) 
                lll = o;
            else
                rrr = o;
        }
        printf("%.15f\n", o);
    }
    return 0;
}

J. Symmetrical Painting

solved at 01:38(+4)

Why map has been MLE ah .....

N has a rectangular two-dimensional plane, the lower left corner of each rectangle is \ ((I -. 1, L_i) \) , the upper right corner is \ ((I, R_i) \) , start all black rectangle, not a plane local coverage of a white rectangle, you take some white-black area (inside a rectangle may be different color), so that the black area is a symmetry axis and the symmetry axis parallel to the x-axis, seeking the maximum black area of

First, when the symmetry axis of ordinate is an integer of either answer obtaining either \ (X.5 \) , enumeration axis of symmetry, maintaining two sets, one for the axis of symmetry of the current partial enumeration rectangular lower half, the upper half represents a part, per 0.5 axisymmetric move up, the first in a set of answers to every element in a contribution, contribution to the second set of -1, then the first set may have a rectangular skip second set ( reaches the midline), may also have a rectangular shape into the first set (arrival at the end), it may have a rectangular out from the second set (onto the bottom)

In fact you do not really need to maintain the collection, only you need to know the size of the set on it

#include <bits/stdc++.h>
using namespace std;

const int N = 3e5 + 10;

int n, L[N], R[N], md[N], m;
long long tmp, ans;
int b[N * 3];
int in[N * 3], change[N * 3], out[N * 3];

int main() {
    scanf("%d", &n);
    for(int i = 1; i <= n; ++i) {
        scanf("%d%d", &L[i], &R[i]);
        L[i] = 2 * L[i] - 1;
        R[i] = 2 * R[i] - 1;
        md[i] = (0LL + L[i] + R[i]) / 2;
        b[3 * i - 2] = L[i];
        b[3 * i - 1] = R[i];
        b[3 * i] = md[i];
    }
    tmp = ans = 0;
    sort(b + 1, b + 3 * n + 1);
    m = unique(b + 1, b + 3 * n + 1) - b - 1;
    for(int i = 1; i <= n; ++i) {
        in[lower_bound(b + 1, b + m + 1, L[i]) - b]++;
        change[lower_bound(b + 1, b + m + 1, md[i]) - b]++;
        out[lower_bound(b + 1, b + m + 1, R[i]) - b]++;
    }
    int down = 0, up = 0;
    down += in[1];
    for(int i = 2; i <= m; ++i) {
        tmp += 1LL * (down - up) * (b[i] - b[i - 1]);
        ans = max(ans, tmp);
        down += in[i];
        down -= change[i];
        up += change[i];
        up -= out[i];
    }
    printf("%lld\n", ans);
    return 0;
}

Guess you like

Origin www.cnblogs.com/tusikalanse/p/11361205.html