2018 Multi-University Training Contest 2

A Absolute


B Counting Permutations


C Cover


D Game

#include <cstdio>
using namespace std;

int main()
{
    int n;
    while(~scanf("%d", &n)) printf("Yes
");
}


E Hack It

构造一个矩阵,使得任何子矩阵的四个角不能都为1。

#include<cstdio>
using namespace std;
const int n = 47;
const int maxn = 3010;
int mp[maxn][maxn];
int main() { for(int i = 0; i < n; i++) for(int j = 0; j < n; j++) for(int k = 0; k < n; k++) mp[i*n+j][k*n+(j*k+i)%n]=1; printf("2000 "); for(int i=0;i<2000;i++) { for(int j=0;j<2000;j++) printf("%d", mp[i][j]); puts(""); } return 0; }


F Matrix


G Naive Operations

用线段树维护每个点被操作了多少次,然后当操作次数是b[i]的整数倍时,将sum[i]++。

新学了一种线段树的写法。

#include <iostream>
#include <cstdlib>
#include <cstdio>
using namespace std;
#define LL long long
const int maxn = 100000 + 10;

struct Sect
{
    int cnt, lz;
    LL sum;

}t[4*maxn];

int n, a[maxn], lim[maxn];

void build(int id, int l, int r)
{
    t[id].lz = 0;
    t[id].sum = 0;
    if (l == r)
    {
        t[id].cnt = lim[l];
        return;
    }
    int mid = (l+r) / 2;
    build(id*2, l, mid);
    build(id*2+1, mid+1, r);
    t[id].sum = t[id*2].sum + t[id*2+1].sum;
    t[id].cnt = min(t[id*2].cnt, t[id*2+1].cnt);
}

void push_down(int id)
{
    if (t[id].lz)
    {
        t[id*2].lz += t[id].lz, t[id*2+1].lz += t[id].lz;
        t[id*2].cnt -= t[id].lz, t[id*2+1].cnt -= t[id].lz;
        t[id].lz = 0;
    }
}

void update_range(int id, int L, int R, int l, int r)
{
    if (t[id].cnt > 1 && L <= l && r <= R)
    {
        t[id].lz++;
        t[id].cnt--;
        return;
    }
    if (t[id].cnt == 1 && l == r)
    {
        t[id].sum++;
        t[id].lz = 0;
        t[id].cnt = lim[l];
        return;
    }
    int mid = (l + r) / 2;
    push_down(id);
    if (L <= mid) update_range(id*2, L, R, l, mid);
    if (R > mid) update_range(id*2+1, L, R, mid+1, r);
    t[id].cnt = min(t[id*2].cnt, t[id*2+1].cnt);
    t[id].sum = t[id*2].sum + t[id*2+1].sum;
}

LL query(int id, int L, int R, int l, int r)
{
    if (L <= l && r <= R) return t[id].sum;
    int mid = (l + r) / 2;
    LL ans = 0;
    push_down(id);
    if (L <= mid) ans += query(id*2, L, R, l, mid);
    if (R > mid) ans += query(id*2+1, L, R, mid+1, r);
    t[id].cnt = min(t[id*2].cnt, t[id*2+1].cnt);
    t[id].sum = t[id*2].sum + t[id*2+1].sum;
    return ans;
}

int main()
{
    int n, q;
    while(scanf("%d%d", &n, &q) != EOF)
    {
        for (int i = 1; i <= n; i++) scanf("%d", &lim[i]);
        build(1, 1, n);
        char op[maxn];
        int x, y;
        for (int i = 1; i <= q; i++)
        {
            scanf("%s%d%d", op, &x, &y);
            if (op[0] == 'a') update_range(1, x, y, 1, n);
                else printf("%lld
", query(1, x, y, 1, n));
        }
    }
}


H Odd Shops


I Segment


J Swaps and Inversions

ans = 逆序对的数量 × min(x, y)

#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
typedef long long LL;
const int maxn = 100000 + 100;

LL cnt = 0;
int T[maxn], a[maxn];

void merge_sort(int *A, int x, int y, int *T)
{
    if (y-x > 1)
    {
        int m = x + (y-x)/2;
        int p = x, q = m, i = x;
        merge_sort(A, x, m, T);
        merge_sort(A, m, y, T);
        while(p < m || q < y)
        {
            if (q >= y || (p < m && A[p] <= A[q])) T[i++] = A[p++];
            else T[i++] = A[q++], cnt += m-p;
        }
        for (i = x; i < y; i++) A[i] = T[i];
    }
}

int main()
{
    int n, x, y;
    while(~scanf("%d%d%d", &n, &x, &y))
    {
        for (int i = 1; i <= n; i++) scanf("%d", &a[i]);
        cnt = 0;
        merge_sort(a, 1, n+1, T);
        LL ans = cnt * min(x, y);
        printf("%lld
", ans);
    }
}
原文地址:https://www.cnblogs.com/ruthank/p/9817381.html