AIM Tech Round 5 (rated, Div. 1 + Div. 2)

Posted kisekipurin2019

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了AIM Tech Round 5 (rated, Div. 1 + Div. 2)相关的知识,希望对你有一定的参考价值。

A - Find Square

没意思。

int n, m;
char g[205][205];

void test_case() {
    scanf("%d%d", &n, &m);
    for(int i = 1; i <= n; ++i)
        scanf("%s", g[i] + 1);
    int l1 = -1, l2 = -1;
    int s1 = -1, s2 = -1;
    for(int i = 1; i <= n; ++i) {
        for(int j = 1; j <= m; ++j) {
            if(g[i][j] == 'B') {
                l1 = i;
                l2 = j;
                if(s1 == -1)
                    s1 = i;
                if(s2 == -1)
                    s2 = j;
            }
        }
    }
    printf("%d %d
", (s1 + l1) / 2, (s2 + l2) / 2);
}

B - Unnatural Conditions

没意思。

int n, m;

void test_case() {
    scanf("%d%d", &n, &m);
    for(int i = 1; i <= 2200; ++i)
        putchar('5');
    putchar('5');
    putchar('
');
    for(int i = 1; i <= 2200; ++i)
        putchar('4');
    putchar('5');
    putchar('
');
}

C - Rectangles

假算法:

int n;
int x1[150005], y1[150005];
int x2[150005], y2[150005];
int xx[300005], yy[300005], top, xtop, ytop;

int dx[300005], dy[300005];
int dx2[300005], dy2[300005];

bool check(int x, int y) {
    printf("x=%d y=%d
", x, y);
    int LX = dx2[x - 1];
    int RX = n - dx[x];
    if(LX + RX >= 2)
        return false;
    int LY = dy2[y - 1];
    int RY = n - dy[y];
    if(LY + RY >= 2)
        return false;
    printf("LX=%d RX=%d LY=%d RY=%d
", LX, RX, LY, RY);
    return true;
}

void test_case() {
    scanf("%d", &n);
    top = 0;
    for(int i = 1; i <= n; ++i) {
        scanf("%d%d%d%d", &x1[i], &y1[i], &x2[i], &y2[i]);
        ++top;
        xx[top] = x1[i];
        yy[top] = y1[i];
        ++top;
        xx[top] = x2[i];
        yy[top] = y2[i];
    }
    sort(xx + 1, xx + 1 + top);
    xtop = unique(xx + 1, xx + 1 + top) - (xx + 1);
    sort(yy + 1, yy + 1 + top);
    ytop = unique(yy + 1, yy + 1 + top) - (yy + 1);
    for(int i = 1; i <= n; ++i) {
        x1[i] = lower_bound(xx + 1, xx + 1 + xtop, x1[i]) - (xx);
        x2[i] = lower_bound(xx + 1, xx + 1 + xtop, x2[i]) - (xx);
        y1[i] = lower_bound(yy + 1, yy + 1 + ytop, y1[i]) - (yy);
        y2[i] = lower_bound(yy + 1, yy + 1 + ytop, y2[i]) - (yy);
        printf("%d %d %d %d
", x1[i], y1[i], x2[i], y2[i]);
    }
    for(int i = 1; i <= n; ++i) {
        ++dx[x1[i]];
        ++dx2[x2[i]];
        ++dy[y1[i]];
        ++dy2[y2[i]];
    }
    for(int i = 1; i <= xtop; ++i) {
        dx[i] += dx[i - 1];
        dx2[i] += dx2[i - 1];
    }
    for(int i = 1; i <= ytop; ++i) {
        dy[i] += dy[i - 1];
        dy2[i] += dy2[i - 1];
    }
    for(int i = 1; i <= n; ++i) {
        if(check(x1[i], y1[i])) {
            printf("%d %d
", xx[x1[i]], yy[y1[i]]);
            return;
        }
        if(check(x1[i], y2[i])) {
            printf("%d %d
", xx[x1[i]], yy[y2[i]]);
            return;
        }
        if(check(x2[i], y1[i])) {
            printf("%d %d
", xx[x2[i]], yy[y1[i]]);
            return;
        }
        if(check(x2[i], y2[i])) {
            printf("%d %d
", xx[x2[i]], yy[y2[i]]);
            return;
        }
    }
}

原因:x和y是不能分开考虑的。过不了第一个样例。

正确做法:扫描线。

int n;
int x1[150005], y1[150005];
int x2[150005], y2[150005];
int xx[300005], yy[300005], top, xtop, ytop;

vector<pii> upd[300005];

struct SegmentTree {
#define ls (o<<1)
#define rs (o<<1|1)
    static const int MAXN = 300000;
    static const int INF = 0x3f3f3f3f;
    int ma[(MAXN << 2) + 5];
    int ps[(MAXN << 2) + 5];
    int lz[(MAXN << 2) + 5];

    void PushUp(int o) {
        if(ma[ls] >= ma[rs]) {
            ma[o] = ma[ls];
            ps[o] = ps[ls];
        } else {
            ma[o] = ma[rs];
            ps[o] = ps[rs];
        }
    }

    void PushDown(int o, int l, int r) {
        if(lz[o]) {
            lz[ls] += lz[o];
            lz[rs] += lz[o];
            ma[ls] += lz[o];
            ma[rs] += lz[o];
            lz[o] = 0;
        }
    }

    void Build(int o, int l, int r) {
        if(l == r) {
            ma[o] = 0;
            ps[o] = l;
        } else {
            int m = l + r >> 1;
            Build(ls, l, m);
            Build(rs, m + 1, r);
            PushUp(o);
        }
        lz[o] = 0;
    }

    void Update(int o, int l, int r, int ql, int qr, int v) {
        if(ql <= l && r <= qr) {
            lz[o] += v;
            ma[o] += v;
        } else {
            PushDown(o, l, r);
            int m = l + r >> 1;
            if(ql <= m)
                Update(ls, l, m, ql, qr, v);
            if(qr >= m + 1)
                Update(rs, m + 1, r, ql, qr, v);
            PushUp(o);
        }
    }

    pii QueryMax(int o, int l, int r, int ql, int qr) {
        if(ql <= l && r <= qr) {
            return {ma[o], ps[o]};
        } else {
            PushDown(o, l, r);
            int m = l + r >> 1;
            pii res = {-INF, -1};
            if(ql <= m)
                res = QueryMax(ls, l, m, ql, qr);
            if(qr >= m + 1) {
                pii tmp = QueryMax(rs, m + 1, r, ql, qr);
                if(tmp.first > res.first)
                    res = tmp;
            }
            return res;
        }
    }
#undef ls
#undef rs
} st;

void test_case() {
    scanf("%d", &n);
    top = 0;
    for(int i = 1; i <= n; ++i) {
        scanf("%d%d%d%d", &x1[i], &y1[i], &x2[i], &y2[i]);
        ++y2[i];
        ++top;
        xx[top] = x1[i];
        yy[top] = y1[i];
        ++top;
        xx[top] = x2[i];
        yy[top] = y2[i];
    }
    sort(xx + 1, xx + 1 + top);
    xtop = unique(xx + 1, xx + 1 + top) - (xx + 1);
    sort(yy + 1, yy + 1 + top);
    ytop = unique(yy + 1, yy + 1 + top) - (yy + 1);
    for(int i = 1; i <= n; ++i) {
        x1[i] = lower_bound(xx + 1, xx + 1 + xtop, x1[i]) - (xx);
        x2[i] = lower_bound(xx + 1, xx + 1 + xtop, x2[i]) - (xx);
        y1[i] = lower_bound(yy + 1, yy + 1 + ytop, y1[i]) - (yy);
        y2[i] = lower_bound(yy + 1, yy + 1 + ytop, y2[i]) - (yy);
        //printf("%d %d %d %d
", x1[i], y1[i], x2[i], y2[i]);
        upd[y1[i]].push_back({x1[i], x2[i]});
        upd[y2[i]].push_back({-x1[i], -x2[i]});
    }
    st.Build(1, 1, xtop);
    for(int i = 1; i <= ytop; ++i) {
        for(int j = 0; j < upd[i].size(); ++j) {
            int l = upd[i][j].first;
            int r = upd[i][j].second;
            if(l > 0 && r > 0)
                st.Update(1, 1, xtop, l, r, 1);
            else
                st.Update(1, 1, xtop, -l, -r, -1);
        }
        pii res = st.QueryMax(1, 1, xtop, 1, xtop);
        if(res.first >= n - 1) {
            int X = res.second;
            int Y = i;
            printf("%d %d
", xx[X], yy[Y]);
            return;
        }
    }
    printf("-1 -1
");
    exit(-1);
}

以上是关于AIM Tech Round 5 (rated, Div. 1 + Div. 2)的主要内容,如果未能解决你的问题,请参考以下文章

AIM Tech Round 5 (rated, Div. 1 + Div. 2) BUnnatural Conditions

AIM Tech Round 5 (rated, Div. 1 + Div. 2) CRectangles

AIM Tech Round 5 (rated, Div. 1 + Div. 2) A Find Square

AIM Tech Round 5 (rated, Div. 1 + Div. 2) 总结题解往前或往后翻,不在这

AIM Tech Round 5 1028cf(A-E)

Codeforces AIM Tech Round3