zoukankan      html  css  js  c++  java
  • 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
    ", ans);
            }
        }
        return 0;
    }
    
    /*
    */
  • 相关阅读:
    HDU 5313 bitset优化背包
    bzoj 2595 斯坦纳树
    COJ 1287 求匹配串在模式串中出现的次数
    HDU 5381 The sum of gcd
    POJ 1739
    HDU 3377 插头dp
    HDU 1693 二进制表示的简单插头dp
    HDU 5353
    URAL 1519 基础插头DP
    UVA 10294 等价类计数
  • 原文地址:https://www.cnblogs.com/CJLHY/p/10987995.html
Copyright © 2011-2022 走看看