Codeforces Round #504 (rated, Div. 1 + Div. 2, based on VK Cup 2018 Final)

A. Single Wildcard Pattern Matching

题解:记 “ * ”的位置为pos(假设存在),那么就顺着匹配 0 ~ (pos - 1),倒着匹配 (pos + 1) ~ n就行了,特判一下 n > m + 1 的情况 和 没有 “ * ”的情况。

B. Pair of Toys

题解:在1 ~ n中找大于 k / 2 + 1的数有多少个。

C. Bracket Subsequence

ps:因为给的串就已经是匹配的了,随便搞

D. Array Restoration

题解:先把所有含0的位置预处理了:如果a序列中出现了q,那么随便一个出现0的位置填上q,然后顺着处理一遍0,逆着处理一遍0:

 for (int i = 1; i <= n; ++i) if (!a[i]) a[i] = a[i - 1];
 for (int i = n; i >= 1; --i) if (!a[i]) a[i] = a[i + 1];

每个数对应的最长区间:

 for (int i = 1; i <= n; ++i) {
        Min[a[i]] = min(Min[a[i]], i);
        Max[a[i]] = max(Max[a[i]], i);
 }

 最后线段树模拟一下询问的过程行了(每个数组的空间一定要开够,因为 use[ ] 只开了2e5,wa 10 wa到气哭)

#include<bits/stdc++.h>
#define ULL unsigned long long
#define LL long long
#define P pair<int, int>
#define pb push_back
#define mp make_pair
#define pp pop_back
#define lson root << 1
#define INF32 (int)2e9 + 7
#define rson root << 1 | 1
#define INF64 (unsigned long long)1e18
#define sc(x) scanf("%d", &x)
#define pr(x) printf("%d
", x)
#define mem(arry, in) memset(arry, in, sizeof(arry))
#define IOS ios_base::sync_with_stdio(0);cin.tie(0);cout.tie(0);
#define BEGIN() int T; sc(T); while(T--)
using namespace std;
/*
namespace fastIO {
    #define BUF_SIZE 100000
    bool IOerror = 0;
    inline char nc() {
        static char buf[BUF_SIZE], *p1 = buf + BUF_SIZE, *pend = buf + BUF_SIZE;
        if(p1 == pend) {
            p1 = buf;
            pend = buf + fread(buf, 1, BUF_SIZE, stdin);
            if(pend == p1) {
                IOerror = 1;
                return -1;
            }
        }
        return *p1++;
    }
    inline bool blank(char ch) {
        return ch == ' ' || ch == '
' || ch == '
' || ch == '	';
    }
    inline void read(int &x) {
        char ch;
        while(blank(ch = nc()));
        if(IOerror) return;
        for(x = ch - '0'; (ch = nc()) >= '0' && ch <= '9'; x = x * 10 + ch - '0');
    }
    #undef BUF_SIZE
};
using namespace fastIO;
*/
inline void upd(int &x, int y) { x < y && (x = y); }

const int N = 200005;

int n, q;
int a[N], Min[N], Max[N], b[4 * N], use[4 * N];

void Inite() {
    mem(Max, 0), mem(use, 0);
    for (int i = 0; i < N; ++i) Min[i] = INF32;
}

void Pushdown(int root) {
    b[lson] = b[rson] = b[root];
    b[root] = 0;
    use[lson] = use[rson] = 1;
    use[root] = 0;
}

void Update(int l, int r, int root, int L, int R, int x) {
    if (l > R || r < L) return;
    if (L <= l && r <= R) {
        b[root] = x;
        use[root] = 1;
        return;
    }
    if (use[root]) Pushdown(root);
    int mid = (l + r) >> 1;
    Update(l, mid, lson, L, R, x);
    Update(mid + 1, r, rson, L, R, x);
}

vector<int> res;

void print(int l, int r, int root) {
    if (l == r) {
        res.pb(b[root]);
        return ;
    }
    if (use[root]) Pushdown(root);
    int mid = (l + r) >> 1;
    print(l, mid, lson);
    print(mid + 1, r, rson);
}

int main()
{
    //freopen("D:\a.in", "r", stdin);
    //freopen("D:\1.txt", "w", stdout);

    Inite();
    res.clear();

    cin >> n >> q;

    int ps = -1;
    bool flag = 0;

    for (int i = 1; i <= n; ++i) {
        cin >> a[i];
        if (a[i] == q) flag = 1;
        if (a[i] && ps == -1) ps = i;
    }

    if (ps == -1) {
        puts("YES");
        for (int i = 1; i <= n; ++i) printf("%d ", q);
        return 0;
    }

    if (!flag) {
        bool vq = 0;
        for (int i = 1; i <= n; ++i) if (!a[i]) {
            a[i] = q;
            vq = 1;
            break;
        }
        if (!vq) {
            puts("NO");
            return 0;
        }
    }

    for (int i = 1; i <= n; ++i) if (!a[i]) a[i] = a[i - 1];
    for (int i = n; i >= 1; --i) if (!a[i]) a[i] = a[i + 1];


    //for (int i = 1; i <= n; ++i) cout << a[i] << " ";
    //cout << endl;

    for (int i = 1; i <= n; ++i) {
        Min[a[i]] = min(Min[a[i]], i);
        Max[a[i]] = max(Max[a[i]], i);
    }

    for (int i = 1; i <= q; ++i) if (Min[i] != INF32) Update(1, n, 1, Min[i], Max[i], i);
    print(1, n, 1);

    for (int i = 0; i < res.size(); ++i) if (res[i] != a[i + 1]) {
        puts("NO");
        return 0;
    }

    puts("YES");
    for (auto x : res) printf("%d ", x);

    return 0;
}
View Code

 E. Down or Right

ps:从两头向中间找,如果(i,j)能到(n,n),那么(i + 1, j)能到(n,n)或者(i,j + 1)能到(n,n)。

inline void upd(int &x, int y) { x < y && (x = y); }

const int N = 200005;

int n, x, y;
string s1 = "", s2 = "";

bool ask(int x1, int y1, int x2, int y2) {
    cout << "? " << x1 << " " << y1 << " " << x2 << " " << y2 << endl;
    string s;
    cin >> s;
    return s == "YES";
}

int main()
{
    //freopen("D:\a.in", "r", stdin);
    //freopen("D:\1.txt", "w", stdout);

    sc(n);
    x = 1, y = 1;

    int t = n - 1;
    while(t--) {
        if (ask(x + 1, y, n, n)) {
            x++;
            s1 = s1 + "D";
        }
        else {
            y++;
            s1 = s1 + "R";
        }
    }

    t = n - 1;
    x = n, y = n;
    while(t--) {
        if (ask(1, 1, x, y - 1)) {
            y--;
            s2 = "R" + s2;
        }
        else {
            x--;
            s2 = "D" + s2;
        }
    }

    cout << "! " << s1 + s2 << endl;

    return 0;
}
View Code
原文地址:https://www.cnblogs.com/zgglj-com/p/9497352.html