NOIP模拟测试11

昨天颓了一天,今天考试没干劲。

Problem A: string

感觉和HEOI2016排序差不多,但刚了半小时没想出来,打了sort的40暴力。

正解确实和那题差不多,线段树存每个区间每种颜色的数目,每次修改开个cnt数组存修改区间每种颜色的数目,从小到大的把数目大小的区间颜色都改了。

这个思路还是蛮好理解的。速码。

TLE。50。

#include <bits/stdc++.h>

const int N = 100000 + 233;
int n, m, sum[N << 2][30], L[N << 2], R[N << 2], lazy[N << 2];
char s[N];

void build(int p, int l, int r) {
    L[p] = l, R[p] = r;
    if (l == r) return (void) (sum[p][s[l] - 'a' + 1] = 1);
    int mid = (l + r) >> 1;
    build(p << 1, l, mid), build(p << 1 | 1, mid + 1, r);
    for (int i = 1; i <= 26; i++)
        sum[p][i] = sum[p << 1][i] + sum[p << 1 | 1][i];
}   

inline void pushdown(int p) {
    if (!lazy[p]) return;
    for (int i = (p << 1); i <= (p << 1 | 1); i++) {
        for (int j = 1; j <= 26; j++) sum[i][j] = 0;
        sum[i][lazy[p]] = R[i] - L[i] + 1, lazy[i] = lazy[p];
    }
    lazy[p] = 0;
}

void change(int p, int l, int r, int k) {
    if (L[p] >= l && R[p] <= r) {
        for (int i = 1; i <= 26; i++) sum[p][i] = 0;
        sum[p][k] = R[p] - L[p] + 1;
        lazy[p] = k;
        return;
    }
    pushdown(p);
    int mid = (L[p] + R[p]) >> 1;
    if (l <= mid) change(p << 1, l, r, k);
    if (r > mid) change(p << 1 | 1, l, r, k);
    for (int i = 1; i <= 26; i++)
        sum[p][i] = sum[p << 1][i] + sum[p << 1 | 1][i];
}

int ask(int p, int l, int r, int k) {
    if (L[p] >= l && R[p] <= r) return sum[p][k];
    pushdown(p);
    int mid = (L[p] + R[p]) >> 1, ret = 0;
    if (l <= mid) ret += ask(p << 1, l, r, k);
    if (r > mid) ret += ask(p << 1 | 1, l, r, k);
    return ret;
}

void print(int p, int l, int r) {
    if (l == r) {
        for (int i = 1; i <= 26; i++)
            if (sum[p][i]) return (void) printf("%c", i + 'a' - 1);
        return;
    }
    pushdown(p);
    int mid = (l + r) >> 1;
    print(p << 1, l, mid), print(p << 1 | 1, mid + 1, r);
}   

signed main() {
    scanf("%d%d%s", &n, &m, s + 1);
    build(1, 1, n);
    for (int i = 1, l, r, x; i <= m; i++) {
        scanf("%d%d%d", &l, &r, &x);
        int cnt[30] = {}, lst = l;
        for (int j = 1; j <= 26; j++) 
            cnt[j] = ask(1, l, r, j);
        if (x == 1)
            for (int j = 1; j <= 26; j++)
                change(1, lst, lst + cnt[j] - 1, j), lst += cnt[j];
        else
            for (int j = 26; j >= 1; j--)
                change(1, lst, lst + cnt[j] - 1, j), lst += cnt[j];
    }
    print(1, 1, n);
    puts("");
    return 0;
}

我草了,这题卡常!!!!

开始卡常:数组紧贴着开,线段树开3倍也可以。

60。

#include <bits/stdc++.h>

const int N = 100000 + 233;
int n, m, sum[N * 3][27], L[N * 3], R[N * 3], lazy[N * 3], cnt[27];
char s[N];

inline int read() {
    int a = 0; char c = getchar();
    while (!isdigit(c)) c = getchar();
    while (isdigit(c)) a = a * 10 + c - '0', c = getchar();
    return a;
}

void build(int p, int l, int r) {
    L[p] = l, R[p] = r;
    if (l == r) return (void) (sum[p][s[l] - 'a' + 1] = 1);
    int mid = (l + r) >> 1;
    build(p << 1, l, mid), build(p << 1 | 1, mid + 1, r);
    for (int i = 1; i <= 26; i++)
        sum[p][i] = sum[p << 1][i] + sum[p << 1 | 1][i];
}   

inline void pushdown(int p) {
    if (!lazy[p]) return;
    for (int i = (p << 1); i <= (p << 1 | 1); i++) {
        for (int j = 1; j <= 26; j++) sum[i][j] = 0;
        sum[i][lazy[p]] = R[i] - L[i] + 1, lazy[i] = lazy[p];
    }
    lazy[p] = 0;
}

void change(int p, int l, int r, int k) {
    if (L[p] >= l && R[p] <= r) {
        for (int i = 1; i <= 26; i++) sum[p][i] = 0;
        sum[p][k] = R[p] - L[p] + 1, lazy[p] = k;
        return;
    }
    pushdown(p);
    int mid = (L[p] + R[p]) >> 1;
    if (l <= mid) change(p << 1, l, r, k);
    if (r > mid) change(p << 1 | 1, l, r, k);
    for (int i = 1; i <= 26; i++)
        sum[p][i] = sum[p << 1][i] + sum[p << 1 | 1][i];
}

void ask(int p, int l, int r) {
    if (L[p] >= l && R[p] <= r){
        for (int i = 1; i <= 26; i++)
            cnt[i] += sum[p][i];
        return;
    }   
    pushdown(p);
    int mid = (L[p] + R[p]) >> 1;
    if (l <= mid) ask(p << 1, l, r);
    if (r > mid) ask(p << 1 | 1, l, r);
}

void print(int p, int l, int r) {
    if (l == r) {
        for (int i = 1; i <= 26; i++)
            if (sum[p][i]) return (void) putchar(i + 'a' - 1);
        return;
    }
    pushdown(p);
    int mid = (l + r) >> 1;
    print(p << 1, l, mid), print(p << 1 | 1, mid + 1, r);
}   

signed main() {
    n = read(), m = read();
    scanf("%s", s + 1);
    build(1, 1, n);
    for (int i = 1, l, r, x; i <= m; i++) {
        l = read(), r = read(), x = read(); 
        int lst = l;
        ask(1, l, r);
        if (x == 1)
            for (int j = 1; j <= 26; j++)
                change(1, lst, lst + cnt[j] - 1, j), lst += cnt[j];
        else
            for (int j = 26; j >= 1; j--)
                change(1, lst, lst + cnt[j] - 1, j), lst += cnt[j];
        for (int i = 1; i <= 26; i++) cnt[i] = 0;
    }
    print(1, 1, n);
    puts("");
    return 0;
}

这时cwy很郁闷,突然想起WC的挑战,N方也能过百万,秘籍:循环展开。

疯狂展开,同时,ask不再返回,把cnt开成全局直接修改。change时候不再循环1-26,cnt不为0再进入change函数。

改了好久,终于A了。

扫描二维码关注公众号,回复: 6924774 查看本文章

AC代码:(344行)

#include <bits/stdc++.h>

const int N = 100000 + 1;
int n, m, sum[N * 3][27], L[N * 3], R[N * 3], lazy[N * 3], cnt[27];
char s[N];

inline int read() {
    int a = 0; char c = getchar();
    while (!isdigit(c)) c = getchar();
    while (isdigit(c)) a = a * 10 + c - '0', c = getchar();
    return a;
}

void build(int p, int l, int r) {
    L[p] = l, R[p] = r;
    if (l == r) return (void) (sum[p][s[l] - 'a' + 1] = 1);
    int mid = (l + r) >> 1;
    build(p << 1, l, mid), build(p << 1 | 1, mid + 1, r);
    sum[p][1] = sum[p << 1][1] + sum[p << 1 | 1][1];
    sum[p][2] = sum[p << 1][2] + sum[p << 1 | 1][2];
    sum[p][3] = sum[p << 1][3] + sum[p << 1 | 1][3];
    sum[p][4] = sum[p << 1][4] + sum[p << 1 | 1][4];
    sum[p][5] = sum[p << 1][5] + sum[p << 1 | 1][5];
    sum[p][6] = sum[p << 1][6] + sum[p << 1 | 1][6];
    sum[p][7] = sum[p << 1][7] + sum[p << 1 | 1][7];
    sum[p][8] = sum[p << 1][8] + sum[p << 1 | 1][8];
    sum[p][9] = sum[p << 1][9] + sum[p << 1 | 1][9];
    sum[p][10] = sum[p << 1][10] + sum[p << 1 | 1][10];
    sum[p][11] = sum[p << 1][11] + sum[p << 1 | 1][11];
    sum[p][12] = sum[p << 1][12] + sum[p << 1 | 1][12];
    sum[p][13] = sum[p << 1][13] + sum[p << 1 | 1][13];
    sum[p][14] = sum[p << 1][14] + sum[p << 1 | 1][14];
    sum[p][15] = sum[p << 1][15] + sum[p << 1 | 1][15];
    sum[p][16] = sum[p << 1][16] + sum[p << 1 | 1][16];
    sum[p][17] = sum[p << 1][17] + sum[p << 1 | 1][17];
    sum[p][18] = sum[p << 1][18] + sum[p << 1 | 1][18];
    sum[p][19] = sum[p << 1][19] + sum[p << 1 | 1][19];
    sum[p][20] = sum[p << 1][20] + sum[p << 1 | 1][20];
    sum[p][21] = sum[p << 1][21] + sum[p << 1 | 1][21];
    sum[p][22] = sum[p << 1][22] + sum[p << 1 | 1][22];
    sum[p][23] = sum[p << 1][23] + sum[p << 1 | 1][23];
    sum[p][24] = sum[p << 1][24] + sum[p << 1 | 1][24];
    sum[p][25] = sum[p << 1][25] + sum[p << 1 | 1][25];
    sum[p][26] = sum[p << 1][26] + sum[p << 1 | 1][26];
}   

void change(int p, int l, int r, int k) {
    if (L[p] >= l && R[p] <= r) {
        sum[p][1] = 0;
        sum[p][2] = 0;
        sum[p][3] = 0;
        sum[p][4] = 0;
        sum[p][5] = 0;
        sum[p][6] = 0;
        sum[p][7] = 0;
        sum[p][8] = 0;
        sum[p][9] = 0;
        sum[p][10] = 0;
        sum[p][11] = 0;
        sum[p][12] = 0;
        sum[p][13] = 0;
        sum[p][14] = 0;
        sum[p][15] = 0;
        sum[p][16] = 0;
        sum[p][17] = 0;
        sum[p][18] = 0;
        sum[p][19] = 0;
        sum[p][20] = 0;
        sum[p][21] = 0;
        sum[p][22] = 0;
        sum[p][23] = 0;
        sum[p][24] = 0;
        sum[p][25] = 0;
        sum[p][26] = 0;
        sum[p][k] = R[p] - L[p] + 1, lazy[p] = k;
        return;
    }
    if (lazy[p]) {
        sum[p << 1][1] = 0;
        sum[p << 1][2] = 0;
        sum[p << 1][3] = 0;
        sum[p << 1][4] = 0;
        sum[p << 1][5] = 0;
        sum[p << 1][6] = 0;
        sum[p << 1][7] = 0;
        sum[p << 1][8] = 0;
        sum[p << 1][9] = 0;
        sum[p << 1][10] = 0;
        sum[p << 1][11] = 0;
        sum[p << 1][12] = 0;
        sum[p << 1][13] = 0;
        sum[p << 1][14] = 0;
        sum[p << 1][15] = 0;
        sum[p << 1][16] = 0;
        sum[p << 1][17] = 0;
        sum[p << 1][18] = 0;
        sum[p << 1][19] = 0;
        sum[p << 1][20] = 0;
        sum[p << 1][21] = 0;
        sum[p << 1][22] = 0;
        sum[p << 1][23] = 0;
        sum[p << 1][24] = 0;
        sum[p << 1][25] = 0;
        sum[p << 1][26] = 0;
        sum[p << 1][lazy[p]] = R[p << 1] - L[p << 1] + 1, lazy[p << 1] = lazy[p];
        sum[p << 1 | 1][1] = 0;
        sum[p << 1 | 1][2] = 0;
        sum[p << 1 | 1][3] = 0;
        sum[p << 1 | 1][4] = 0;
        sum[p << 1 | 1][5] = 0;
        sum[p << 1 | 1][6] = 0;
        sum[p << 1 | 1][7] = 0;
        sum[p << 1 | 1][8] = 0;
        sum[p << 1 | 1][9] = 0;
        sum[p << 1 | 1][10] = 0;
        sum[p << 1 | 1][11] = 0;
        sum[p << 1 | 1][12] = 0;
        sum[p << 1 | 1][13] = 0;
        sum[p << 1 | 1][14] = 0;
        sum[p << 1 | 1][15] = 0;
        sum[p << 1 | 1][16] = 0;
        sum[p << 1 | 1][17] = 0;
        sum[p << 1 | 1][18] = 0;
        sum[p << 1 | 1][19] = 0;
        sum[p << 1 | 1][20] = 0;
        sum[p << 1 | 1][21] = 0;
        sum[p << 1 | 1][22] = 0;
        sum[p << 1 | 1][23] = 0;
        sum[p << 1 | 1][24] = 0;
        sum[p << 1 | 1][25] = 0;
        sum[p << 1 | 1][26] = 0;
        sum[p << 1 | 1][lazy[p]] = R[p << 1 | 1] - L[p << 1 | 1] + 1, lazy[p << 1 | 1] = lazy[p];
        lazy[p] = 0;
    }
    int mid = (L[p] + R[p]) >> 1;
    if (l <= mid) change(p << 1, l, r, k);
    if (r > mid) change(p << 1 | 1, l, r, k);
    sum[p][1] = sum[p << 1][1] + sum[p << 1 | 1][1];
    sum[p][2] = sum[p << 1][2] + sum[p << 1 | 1][2];
    sum[p][3] = sum[p << 1][3] + sum[p << 1 | 1][3];
    sum[p][4] = sum[p << 1][4] + sum[p << 1 | 1][4];
    sum[p][5] = sum[p << 1][5] + sum[p << 1 | 1][5];
    sum[p][6] = sum[p << 1][6] + sum[p << 1 | 1][6];
    sum[p][7] = sum[p << 1][7] + sum[p << 1 | 1][7];
    sum[p][8] = sum[p << 1][8] + sum[p << 1 | 1][8];
    sum[p][9] = sum[p << 1][9] + sum[p << 1 | 1][9];
    sum[p][10] = sum[p << 1][10] + sum[p << 1 | 1][10];
    sum[p][11] = sum[p << 1][11] + sum[p << 1 | 1][11];
    sum[p][12] = sum[p << 1][12] + sum[p << 1 | 1][12];
    sum[p][13] = sum[p << 1][13] + sum[p << 1 | 1][13];
    sum[p][14] = sum[p << 1][14] + sum[p << 1 | 1][14];
    sum[p][15] = sum[p << 1][15] + sum[p << 1 | 1][15];
    sum[p][16] = sum[p << 1][16] + sum[p << 1 | 1][16];
    sum[p][17] = sum[p << 1][17] + sum[p << 1 | 1][17];
    sum[p][18] = sum[p << 1][18] + sum[p << 1 | 1][18];
    sum[p][19] = sum[p << 1][19] + sum[p << 1 | 1][19];
    sum[p][20] = sum[p << 1][20] + sum[p << 1 | 1][20];
    sum[p][21] = sum[p << 1][21] + sum[p << 1 | 1][21];
    sum[p][22] = sum[p << 1][22] + sum[p << 1 | 1][22];
    sum[p][23] = sum[p << 1][23] + sum[p << 1 | 1][23];
    sum[p][24] = sum[p << 1][24] + sum[p << 1 | 1][24];
    sum[p][25] = sum[p << 1][25] + sum[p << 1 | 1][25];
    sum[p][26] = sum[p << 1][26] + sum[p << 1 | 1][26];
}

void ask(int p, int l, int r) {
    if (L[p] >= l && R[p] <= r){
        cnt[1] += sum[p][1];
        cnt[2] += sum[p][2];
        cnt[3] += sum[p][3];
        cnt[4] += sum[p][4];
        cnt[5] += sum[p][5];
        cnt[6] += sum[p][6];
        cnt[7] += sum[p][7];
        cnt[8] += sum[p][8];
        cnt[9] += sum[p][9];
        cnt[10] += sum[p][10];
        cnt[11] += sum[p][11];
        cnt[12] += sum[p][12];
        cnt[13] += sum[p][13];
        cnt[14] += sum[p][14];
        cnt[15] += sum[p][15];
        cnt[16] += sum[p][16];
        cnt[17] += sum[p][17];
        cnt[18] += sum[p][18];
        cnt[19] += sum[p][19];
        cnt[20] += sum[p][20];
        cnt[21] += sum[p][21];
        cnt[22] += sum[p][22];
        cnt[23] += sum[p][23];
        cnt[24] += sum[p][24];
        cnt[25] += sum[p][25];
        cnt[26] += sum[p][26];
        return;
    }   
    if (lazy[p]) {
        sum[p << 1][1] = 0;
        sum[p << 1][2] = 0;
        sum[p << 1][3] = 0;
        sum[p << 1][4] = 0;
        sum[p << 1][5] = 0;
        sum[p << 1][6] = 0;
        sum[p << 1][7] = 0;
        sum[p << 1][8] = 0;
        sum[p << 1][9] = 0;
        sum[p << 1][10] = 0;
        sum[p << 1][11] = 0;
        sum[p << 1][12] = 0;
        sum[p << 1][13] = 0;
        sum[p << 1][14] = 0;
        sum[p << 1][15] = 0;
        sum[p << 1][16] = 0;
        sum[p << 1][17] = 0;
        sum[p << 1][18] = 0;
        sum[p << 1][19] = 0;
        sum[p << 1][20] = 0;
        sum[p << 1][21] = 0;
        sum[p << 1][22] = 0;
        sum[p << 1][23] = 0;
        sum[p << 1][24] = 0;
        sum[p << 1][25] = 0;
        sum[p << 1][26] = 0;
        sum[p << 1][lazy[p]] = R[p << 1] - L[p << 1] + 1, lazy[p << 1] = lazy[p];
        sum[p << 1 | 1][1] = 0;
        sum[p << 1 | 1][2] = 0;
        sum[p << 1 | 1][3] = 0;
        sum[p << 1 | 1][4] = 0;
        sum[p << 1 | 1][5] = 0;
        sum[p << 1 | 1][6] = 0;
        sum[p << 1 | 1][7] = 0;
        sum[p << 1 | 1][8] = 0;
        sum[p << 1 | 1][9] = 0;
        sum[p << 1 | 1][10] = 0;
        sum[p << 1 | 1][11] = 0;
        sum[p << 1 | 1][12] = 0;
        sum[p << 1 | 1][13] = 0;
        sum[p << 1 | 1][14] = 0;
        sum[p << 1 | 1][15] = 0;
        sum[p << 1 | 1][16] = 0;
        sum[p << 1 | 1][17] = 0;
        sum[p << 1 | 1][18] = 0;
        sum[p << 1 | 1][19] = 0;
        sum[p << 1 | 1][20] = 0;
        sum[p << 1 | 1][21] = 0;
        sum[p << 1 | 1][22] = 0;
        sum[p << 1 | 1][23] = 0;
        sum[p << 1 | 1][24] = 0;
        sum[p << 1 | 1][25] = 0;
        sum[p << 1 | 1][26] = 0;
        sum[p << 1 | 1][lazy[p]] = R[p << 1 | 1] - L[p << 1 | 1] + 1, lazy[p << 1 | 1] = lazy[p];
        lazy[p] = 0;
    }
    int mid = (L[p] + R[p]) >> 1;
    if (l <= mid) ask(p << 1, l, r);
    if (r > mid) ask(p << 1 | 1, l, r);
}

void print(int p, int l, int r) {
    if (l == r) {
        if (sum[p][1]) return (void) putchar('a');
        if (sum[p][2]) return (void) putchar('b');
        if (sum[p][3]) return (void) putchar('c');
        if (sum[p][4]) return (void) putchar('d');
        if (sum[p][5]) return (void) putchar('e');
        if (sum[p][6]) return (void) putchar('f');
        if (sum[p][7]) return (void) putchar('g');
        if (sum[p][8]) return (void) putchar('h');
        if (sum[p][9]) return (void) putchar('i');
        if (sum[p][10]) return (void) putchar('j');
        if (sum[p][11]) return (void) putchar('k');
        if (sum[p][12]) return (void) putchar('l');
        if (sum[p][13]) return (void) putchar('m');
        if (sum[p][14]) return (void) putchar('n');
        if (sum[p][15]) return (void) putchar('o');
        if (sum[p][16]) return (void) putchar('p');
        if (sum[p][17]) return (void) putchar('q');
        if (sum[p][18]) return (void) putchar('r');
        if (sum[p][19]) return (void) putchar('s');
        if (sum[p][20]) return (void) putchar('t');
        if (sum[p][21]) return (void) putchar('u');
        if (sum[p][22]) return (void) putchar('v');
        if (sum[p][23]) return (void) putchar('w');
        if (sum[p][24]) return (void) putchar('x');
        if (sum[p][25]) return (void) putchar('y');
        if (sum[p][26]) return (void) putchar('z');
        return;
    }
    if (lazy[p]) {
        for (int i = L[p]; i <= R[p]; i++)
            putchar('a' + lazy[p] - 1);
        return;
    }
    int mid = (l + r) >> 1;
    print(p << 1, l, mid), print(p << 1 | 1, mid + 1, r);
}   

signed main() {
    n = read(), m = read();
    scanf("%s", s + 1);
    build(1, 1, n);
    for (int i = 1, l, r, x; i <= m; i++) {
        l = read(), r = read(), x = read(); 
        int lst = l;
        ask(1, l, r);
        if (x == 1) {
            for (int j = 1; j <= 26 && lst <= n; j++)
                if (cnt[j] != 0)
                    change(1, lst, lst + cnt[j] - 1, j), lst += cnt[j];
        } else {
            for (int j = 26; j >= 1 && lst <= n; j--)
                if (cnt[j] != 0)
                    change(1, lst, lst + cnt[j] - 1, j), lst += cnt[j];
        }
        cnt[1] = 0;
        cnt[2] = 0;
        cnt[3] = 0;
        cnt[4] = 0;
        cnt[5] = 0;
        cnt[6] = 0;
        cnt[7] = 0;
        cnt[8] = 0;
        cnt[9] = 0;
        cnt[10] = 0;
        cnt[11] = 0;
        cnt[12] = 0;
        cnt[13] = 0;
        cnt[14] = 0;
        cnt[15] = 0;
        cnt[16] = 0;
        cnt[17] = 0;
        cnt[18] = 0;
        cnt[19] = 0;
        cnt[20] = 0;
        cnt[21] = 0;
        cnt[22] = 0;
        cnt[23] = 0;
        cnt[24] = 0;
        cnt[25] = 0;
        cnt[26] = 0;
    }
    print(1, 1, n);
    puts("");
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/gekoo/p/11285382.html