Codeforces 610E Alphabet Permutations 线段树

Alphabet Permutations

转换一下, 本质就是求相邻的逆序对个数, 每次询问只是给个比较方式。

然后用线段树维护各种相邻逆序对的个数。

这个区间修改成一个数的都能用set维护的。

#include<bits/stdc++.h>
#define LL long long
#define LD long double
#define ull unsigned long long
#define fi first
#define se second
#define mk make_pair
#define PLL pair<LL, LL>
#define PLI pair<LL, int>
#define PII pair<int, int>
#define SZ(x) ((int)x.size())
#define ALL(x) (x).begin(), (x).end()
#define fio ios::sync_with_stdio(false); cin.tie(0);

using namespace std;

const int N = 2e5 + 7;
const int inf = 0x3f3f3f3f;
const LL INF = 0x3f3f3f3f3f3f3f3f;
const int mod = 1e9 + 7;
const double eps = 1e-8;
const double PI = acos(-1);

template<class T, class S> inline void add(T& a, S b) {a += b; if(a >= mod) a -= mod;}
template<class T, class S> inline void sub(T& a, S b) {a -= b; if(a < 0) a += mod;}
template<class T, class S> inline bool chkmax(T& a, S b) {return a < b ? a = b, true : false;}
template<class T, class S> inline bool chkmin(T& a, S b) {return a > b ? a = b, true : false;}

int n, m, k;
char s[N];
int pos[20];

#define lson l, mid, rt << 1
#define rson mid + 1, r, rt << 1 | 1
struct info {
    int c[10][10];
    int cl, cr;
} Tree[N << 2];
int lazy[N << 2];

info operator + (const info &a, const info &b) {
    info c;
    for(int i = 0; i < k; i++)
        for(int j = 0; j < k; j++)
            c.c[i][j] = a.c[i][j] + b.c[i][j];
    c.cl = a.cl; c.cr = b.cr;
    c.c[a.cr][b.cl]++;
    return c;
}

inline void gao(int c, int rt, int l, int r) {
    for(int i = 0; i < k; i++)
        for(int j = 0; j < k; j++)
            Tree[rt].c[i][j] = 0;
    Tree[rt].c[c][c] = r - l;
    Tree[rt].cl = Tree[rt].cr = c;
    lazy[rt] = c;
}

inline void pull(int rt) {
    Tree[rt] = Tree[rt << 1] + Tree[rt << 1 | 1];
}

inline void push(int rt, int l, int r) {
    if(~lazy[rt]) {
        int mid = l + r >> 1;
        gao(lazy[rt], rt << 1, l, mid);
        gao(lazy[rt], rt << 1 | 1, mid + 1, r);
        lazy[rt] = -1;
    }
}

void build(int l, int r, int rt) {
    lazy[rt] = -1;
    if(l == r) {
        Tree[rt].cl = Tree[rt].cr = s[l] - 'a';
        return;
    }
    int mid = l + r >> 1;
    build(lson); build(rson);
    pull(rt);
}

void update(int L, int R, int c, int l, int r, int rt) {
    if(R < l || r < L || R < L) return;
    if(L <= l && r <= R) {
        gao(c, rt, l, r);
        return;
    }
    push(rt, l, r);
    int mid = l + r >> 1;
    update(L, R, c, lson);
    update(L, R, c, rson);
    pull(rt);
}

int main() {
    scanf("%d%d%d", &n, &m, &k);
    scanf("%s", s + 1);
    build(1, n, 1);
    while(m--) {
        int op; scanf("%d", &op);
        if(op == 1) {
            int L, R;
            scanf("%d%d%s", &L, &R, s);
            update(L, R, s[0] - 'a', 1, n, 1);
        } else {
            scanf("%s", s + 1);
            int ans = 1;
            for(int i = 1; i <= k; i++) {
                for(int j = i; j <= k; j++) {
                    ans += Tree[1].c[s[j] - 'a'][s[i] - 'a'];
                }
            }
            printf("%d\n", ans);
        }
    }
    return 0;
}

/*
*/

猜你喜欢

转载自www.cnblogs.com/CJLHY/p/10987995.html
今日推荐