CodeForces Gym 101620簡要題解

來源:互聯網
上載者:User
Assignment Algorithm

類比。

#include <bits/stdc++.h>#define xx first#define yy second#define mp make_pair#define pb push_back#define mset(x, y) memset(x, y, sizeof x)#define mcpy(x, y) memcpy(x, y, sizeof x)using namespace std;typedef long long LL;typedef pair <int, int> pii;inline int Read(){    int x = 0, f = 1, c = getchar();    for (; !isdigit(c); c = getchar())        if (c == '-')            f = -1;    for (;  isdigit(c); c = getchar())        x = x * 10 + c - '0';    return x * f;}const int MAXN = 55;char a[MAXN][MAXN];int n, m;inline void Solve(char c){    vector <pii> row;    int cnt_1 = 0, cnt_2 = 0, t = 1, l = 0, r = 0;    for (int j = 0; j < 11; j ++)        cnt_1 += a[1][j] == '-', cnt_2 += a[n / 2 + 2][j] == '-';    if (cnt_1 || cnt_2)    {        if (cnt_1)            row.pb(mp(cnt_1, 1));        if (cnt_2)            row.pb(mp(cnt_2, n / 2 + 2));    }    else    {        for (int i = 0; i < n + 3; i ++)        {            int cnt = 0;            for (int j = 0; j < 11; j ++)                cnt += a[i][j] == '-';            if (cnt)                row.pb(mp(cnt, i));        }    }    sort(row.begin(), row.end(), greater <pii> ());    for (int i = 1; i < row.size(); i ++)        if (row[i].xx == row[0].xx)            t = i + 1;    for (int i = 0; i < t; i ++)        row[i].xx = min(min(row[i].yy, n + 2 - row[i].yy), abs(row[i].yy - (n / 2 + 1)));    sort(row.begin(), row.begin() + t);    for (int i = 0; i < n + 3; i ++)    {        for (int j = 0; j < 5; j ++)            l += a[i][j] == '-';        for (int j = 6; j < 11; j ++)            r += a[i][j] == '-';    }    int idx = row[0].yy;    if (a[idx][4] == '-' || a[idx][6] == '-')    {        if (a[idx][4] != '-')            a[idx][6] = c;        else if (a[idx][6] != '-')            a[idx][4] = c;        else if (l >= r)            a[idx][4] = c;        else            a[idx][6] = c;    }    else if (a[idx][2] == '-' || a[idx][8] == '-')    {        if (a[idx][2] != '-')            a[idx][8] = c;        else if (a[idx][8] != '-')            a[idx][2] = c;        else if (l >= r)            a[idx][2] = c;        else            a[idx][8] = c;    }    else if (a[idx][0] == '-' || a[idx][10] == '-')    {        if (a[idx][0] != '-')            a[idx][10] = c;        else if (a[idx][10] != '-')            a[idx][0] = c;        else if (l >= r)            a[idx][0] = c;        else            a[idx][10] = c;    }    else if (a[idx][5] == '-')    {        a[idx][5] = c;    }    else    {        if (a[idx][1] != '-')            a[idx][9] = c;        else if (a[idx][9] != '-')            a[idx][1] = c;        else if (l >= r)            a[idx][1] = c;        else            a[idx][9] = c;    }}int main(){#ifdef wxh010910    freopen("data.in", "r", stdin);#endif    n = Read(), m = Read();    for (int i = 0; i < n + 3; i ++)        scanf("%s", a[i]);    for (int i = 0; i < m; i ++)        Solve(i + 'a');    for (int i = 0; i < n + 3; i ++, putchar(10))        for (int j = 0; j < 11; j ++)            putchar(a[i][j]);    return 0;}
Buffalo Barricades

從上到下掃描線,用 set \texttt{set}維護當前的情況,並記錄每個點的父親,最後並查集掃一遍維護。

#include <bits/stdc++.h>#define xx first#define yy second#define mp make_pair#define pb push_back#define mset(x, y) memset(x, y, sizeof x)#define mcpy(x, y) memcpy(x, y, sizeof x)using namespace std;typedef long long LL;typedef pair <int, int> pii;inline int Read(){    int x = 0, f = 1, c = getchar();    for (; !isdigit(c); c = getchar())        if (c == '-')            f = -1;    for (;  isdigit(c); c = getchar())        x = x * 10 + c - '0';    return x * f;}const int MAXN = 300005;struct Event{    int typ, x, y, i;    bool operator < (const Event &b) const    {        return y > b.y || (y == b.y && typ > b.typ);    }} a[MAXN << 1];int n, m, f[MAXN], tmp[MAXN], tag[MAXN], ans[MAXN], par[MAXN];set <pii> s;inline int Find(int x){    while (x ^ f[x])        x = f[x] = f[f[x]];    return x;}inline void Merge(int x, int y){    if (x ^ y)        f[x] = y, tag[y] += tag[x];}int main(){#ifdef wxh010910    freopen("data.in", "r", stdin);#endif    n = Read();    for (int i = 1; i <= n; i ++)        a[i].x = Read(), a[i].y = Read(), a[i].i = i, a[i].typ = 1;    m = Read();    for (int i = n + 1; i <= n + m; i ++)        a[i].x = Read(), a[i].y = Read(), a[i].i = i - n, a[i].typ = 2;    sort(a + 1, a + n + m + 1);    for (int i = 1; i <= n + m; i ++)        if (a[i].typ == 1)        {            auto it = s.lower_bound(mp(a[i].x, -1));            if (it != s.end())                tmp[it -> yy] ++;        }        else        {            auto it = s.insert(mp(a[i].x, a[i].i)).xx, jt = it;            if (jt != -- s.end())                par[a[i].i] = (++ jt) -> yy;            while (it != s.begin())            {                jt = it, jt --;                if (jt -> yy > a[i].i)                    s.erase(jt);                else                    break;            }        }    for (int i = 1; i <= m; i ++)        f[i] = i;    for (int i = m; i; i --)        ans[i] = tag[Find(i)] += tmp[i], Merge(Find(i), Find(par[i]));    for (int i = 1; i <= m; i ++)        printf("%d\n", ans[i]);    return 0;}
Cumulative Code

記 fk(x) f_k(x)表示 k k層的子樹的 prufer \texttt{prufer}序列和, f(x)=ax+bx2+c f(x) = ax + b\frac{x}{2} + c,然後就可以遞推了。

詢問的時候記憶化搜尋,將 k k層及以下的情況記下來,注意一些邊界情況。

#include <bits/stdc++.h>#define xx first#define yy second#define mp make_pair#define pb push_back#define mset(x, y) memset(x, y, sizeof x)#define mcpy(x, y) memcpy(x, y, sizeof x)using namespace std;typedef long long LL;typedef pair <int, int> pii;inline int Read(){    int x = 0, f = 1, c = getchar();    for (; !isdigit(c); c = getchar())        if (c == '-')            f = -1;    for (;  isdigit(c); c = getchar())        x = x * 10 + c - '0';    return x * f;}const int MAXN = 32780;struct Node{    LL a, b, c;    Node(LL a = 0, LL b = 0, LL c = 0):a(a), b(b), c(c) {}    Node operator + (const Node &d) const { return Node(a + 2 * d.a + d.b, b, c + d.c); };    Node operator - (const Node &d) const { return Node(a + 2 * d.a + d.b, b, c + d.c + d.a); }} f[16][MAXN];int tim, vis[16][MAXN];inline Node Solve(int n, int a, int d, int m, bool p){    if (n == 1)        return Node(0, 1, 0);    bool mem = n <= 15 && a + d * m >= (1 << n) - 1 && p;    if (mem && vis[n][a] == tim)        return f[n][a];    Node ret(0, 0, 0);    int cur = a;    if (cur < (1 << n - 1) - 1 && m)    {        int t = min(m, ((1 << n - 1) - 1 - cur - 1) / d + 1);        ret = ret + Solve(n - 1, cur, d, t, true), cur += t * d, m -= t;    }    cur -= (1 << n - 1) - 1;    if (!p)    {        if (!cur && m)            m --, cur += d, ret.a += 2, ret.c ++;        cur --;    }    if (cur < (1 << n - 1) - 1 && m)    {        int t = min(m, ((1 << n - 1) - 1 - cur - 1) / d + 1);        ret = ret - Solve(n - 1, cur, d, t, p), cur += t * d, m -= t;    }    cur -= (1 << n - 1) - 1;    if (p && m)        ret.b ++;    if (mem)        vis[n][a] = tim, f[n][a] = ret;    return ret;}int main(){#ifdef wxh010910    freopen("data.in", "r", stdin);#endif    int n = Read(), q = Read();    while (q --)    {        int a = Read() - 1, d = Read(), m = Read();        tim ++;        Node ret = Solve(n, a, d, m, false);        printf("%lld\n", ret.a + ret.c);    }    return 0;}
Donut Drone

將 (x,0)

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.