2019 Hang electric multi-school first

2019 Hang electric multi-school first

A little autistic, should have been written yesterday, dragged today

1001. Blank

upsolved

In the meaning of the title is \ (n-\) to fill several positions, only fill \ (0,1,2,3 \) of the four, then there is \ (m \) a constraint, limiting the number of different sections number, the program seeking to fill count \ (1 <= n, m <= 100 \)

Looking at the official solution to a problem you will understand

\ (dp [i] [j ] [k] [t] \) before filling out the representative \ (T \) after the occurrence position number four kinds of numbers are sorted considerably small \ (i, j, k, t \ ) the number of programs, constraints applied to the right end is judged like, \ (T \) that dimension can roll off time complexity \ (O (Tn of ^. 4) \) (because \ (i, j , k, t \) ordered so that a constant), a much less complex than the space of \ (O (n ^ 3) \)

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

const int N = 101, mod = 998244353;

int dp[N][N][N][2], T, n, m, l, r, x, ans;

vector<pair<int, int>> cons[N];

void addmod(int &x, int y) {
    x += y;
    if(x >= mod)
        x -= mod;
}

int main() {
    scanf("%d", &T);
    while(T--) {
        ans = 0;
        scanf("%d%d", &n, &m);
        for(int i = 1; i <= m; ++i) {
            scanf("%d%d%d", &l, &r, &x);
            cons[r].push_back({l, x});
        }
        for(int i = 1; i <= n; ++i)
            cons[i].push_back({i, 1});
        memset(dp, 0, sizeof(dp));
        dp[0][0][0][0] = 1;
        for(int cur = 1; cur <= n; ++cur) {
            int o = cur & 1;
            for(int i = 0; i <= cur; ++i) 
                for(int j = i; j <= cur; ++j)
                    for(int k = j; k <= cur; ++k)
                        dp[i][j][k][o] = 0;
            for(int i = 0; i <= cur; ++i) 
                for(int j = i; j <= cur; ++j)
                    for(int k = j; k <= cur; ++k) {
                        addmod(dp[j][k][cur - 1][o], dp[i][j][k][o ^ 1]);
                        addmod(dp[i][k][cur - 1][o], dp[i][j][k][o ^ 1]);
                        addmod(dp[i][j][cur - 1][o], dp[i][j][k][o ^ 1]);
                        addmod(dp[i][j][k][o], dp[i][j][k][o ^ 1]);
                    }
            for(int i = 0; i <= cur; ++i) {
                for(int j = i; j <= cur; ++j)
                    for(int k = j; k <= cur; ++k) 
                        for(auto c : cons[cur]) {
                            l = c.first, x = c.second;
                            if((i >= l) + (j >= l) + (k >= l) + (cur >= l) != x)
                                dp[i][j][k][o] = 0;
                        }
            }
        }
        for(int i = 0; i <= n; ++i)
            for(int j = i; j <= n; ++j) 
                for(int k = j; k <= n; ++k)
                    addmod(ans, dp[i][j][k][n & 1]);
        printf("%d\n", ans);
        for(int i = 1; i <= n; ++i)
            cons[i].clear();
    }
    return 0;
}

1002. Operation

upsloved

By force, to the end of each series interrogation interval adder or exclusive or subset of maximum

Ultimate autistic, cf1100F original title (there are online practice), this problem when it comes to winter I did. . . Then watched five hours did not see it. . .

Is to record \ (\ n-) prefix linear groups, a linear group additionally maintain the insertion position of the number of the current position, insertion of the greedy takes a maximum value, the specific explanations can be found cf1100F

1004. Vacation

solved at 02:40

There \ (n + 1 \) vehicles, each vehicle has a length of maximum speed and the distance from the end, can not overtake, close to the front of the car can go the furthest away from the end to ask the car to reach the end of time

Half of his teammates came up with the answer practice

Linear approach: the farthest away from the end of the last car is definitely and several other vehicles (may be it's own) together through the end of, \ (O (the n-) \) enumeration takes the maximum value just fine

1005. Path

solved at 02:06

There is a directed graph, an edge is the cost of the removal of this edge length, it requires minimal cost from such \ (1 \) to the \ (n-\) shortest path becomes long

The shortest side of the road out to build a new plan to run minimal cut on the line

His teammates did not build a new map point mark crazy \ ({\ RM MLE} \) ...

1006. Typewriter

upsolved

Construction of the target string with the smallest cost, you have an empty string beginning with two operation

\ (1 \) : spend \ (p \) the cost to your last plus a character string

\ (2 \) : spend \ (q \) the cost to you of your strings last plus a string of arbitrary substring

Read the game up a fake title. . .

Maintain two locations \ (i, j \)

\ (s [1: j- 1] \) is inserted \ ({\ RM the SAM} \) , then look \ (s [j: i] \) is not \ (s [1: j- 1] \) of substring

Not to insert \ (s [j], j ++ \)

It is \ (dp [i] = min (dp [i - 1] + p, dp [j-1] + q]) \)

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

const int N = 2e5 + 10;

int nxt[N << 1][26], len[N << 1], par[N << 1];
int sz, last;
char s[N];
int n, p, q;
long long dp[N];

int newnode(int l) {
    len[sz] = l;
    memset(nxt[sz], 0, sizeof(nxt[sz]));
    return sz++;
}

void init() {
    sz = last = 0;
    par[sz] = -1;
    newnode(0);
}

void add(int x) {
    int p = last, np = newnode(len[last] + 1);
    for(; ~p && !nxt[p][x]; p = par[p]) nxt[p][x] = np;
    if(p == -1) {
        par[np] = 0;
    }
    else {
        int q = nxt[p][x];
        if(len[q] == len[p] + 1) {
            par[np] = q;
        }
        else {
            int nq = newnode(len[p] + 1);
            memcpy(nxt[nq], nxt[q], sizeof(nxt[nq]));
            par[nq] = par[q];
            par[q] = par[np] = nq;
            for(; ~p && nxt[p][x] == q; p = par[p])
                nxt[p][x] = nq;
        }
    }
    last = np;
}


int main() {
    while(~scanf("%s%d%d", s + 1, &p, &q)) {
        init();
        n = strlen(s + 1);
        int cur = 1, now = 1, pos = 0;
        while(cur <= n) {
            int x = s[cur] - 'a';
            if(nxt[pos][x]) {
                pos = nxt[pos][x];
                dp[cur] = min(dp[cur - 1] + p, dp[now - 1] + q);
                cur++;
            }
            else if(cur == now) {
                add(x);
                dp[cur] = dp[cur - 1] + p;
                cur++;
                now++;
            }
            else {
                add(s[now++] - 'a');
                int tlen = cur - now;
                while(~pos && ~par[pos] && len[par[pos]] >= tlen)
                    pos = par[pos];
            }
        }
        printf("%lld\n", dp[n]);
    }
    return 0;
}

1009. String

upsolved

Race teammate said to do, but I have been in 1002 ... I really dishes

Selecting a length for a given string is \ (K \) sequence constituting the target string, the lexicographically smallest required, also given \ (26 \) species letters number of occurrences in the upper and lower bounds new string

Direct greedy get away. . .

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

const int N = 1e5 + 10, knd = 26;

char s[N];
int L[knd], R[knd], cnt[N][knd], c[knd], n, k, nxt[N][knd], pos, tmp, tot;
char ans[N];

bool check(int p, int now) {
    if(p < 0) return false;
    int x = s[p] - 'a', res = 0, ret = 1;
    if(c[x] == R[x]) return false;
    c[x]++;
    for(int i = 0; i < knd; ++i) {
        if(L[i] > c[i]) res += L[i] - c[i];
        if(cnt[p][i] - (x == i) < L[i] - c[i]) {
            ret = 0;
            break;
        }
    }
    if(res > k - now) 
        ret = 0;
    c[x]--;
    return ret;
}

int main() {
    while(~scanf("%s%d", s, &k)) {
        tot = 0;
        n = strlen(s);
        for(int i = 0; i < knd; ++i) {
            scanf("%d%d", &L[i], &R[i]);
            tot += R[i];
        }
        memset(nxt[n], -1, sizeof(nxt[n]));
        memset(cnt[n], 0, sizeof(cnt[n]));
        memset(c, 0, sizeof(c));
        for(int i = n - 1; ~i; --i) {
            memcpy(nxt[i], nxt[i + 1], sizeof(nxt[i + 1]));
            memcpy(cnt[i], cnt[i + 1], sizeof(cnt[i + 1]));
            nxt[i][s[i] - 'a'] = i;
            cnt[i][s[i] - 'a']++;
        }
        pos = -1;
        for(int i = 0; i < knd; ++i) {
            if(check(nxt[0][i], 1)) {
                c[i]++;
                pos = nxt[0][i] + 1;
                ans[0] = 'a' + i;
                break;
            }
        }
        if(pos == -1 || tot < k) {
            puts("-1");
            continue;
        }
        for(int i = 1; i < k; ++i) {
            for(int j = 0; j < knd; ++j) {
                if(c[j] == R[j]) continue;
                if(check(nxt[pos][j], i + 1)) {
                    c[j]++;
                    pos = nxt[pos][j] + 1;
                    ans[i] = 'a' + j;
                    break;
                }
            }
        }
        ans[k] = '\0';
        printf("%s\n", ans);
    }
    return 0;
}

1012. Sequence

NTT

Reference blog

1011,1013 are responsible for the direction of his teammates. .

This dish is really playing, the audience no contributions after learning what new things should still be recorded ah. . .

Guess you like

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