• Codeforces Round #312 (Div. 2) E. A Simple Task 线段树 延时标记


    E. A Simple Task
    time limit per test5 seconds
    memory limit per test512 megabytes
    inputstandard input
    outputstandard output
    This task is very simple. Given a string S of length n and q queries each query is on the format i j k which means sort the substring consisting of the characters from i to j in non-decreasing order if k = 1 or in non-increasing order if k = 0.

    Output the final string after applying the queries.

    Input
    The first line will contain two integers n, q (1 ≤ n ≤ 105, 0 ≤ q ≤ 50 000), the length of the string and the number of queries respectively.

    Next line contains a string S itself. It contains only lowercase English letters.

    Next q lines will contain three integers each i, j, k (1 ≤ i ≤ j ≤ n, ).

    Output
    Output one line, the string S after applying the queries.

    Sample test(s)
    input
    10 5
    abacdabcda
    7 10 0
    5 8 1
    1 4 0
    3 6 0
    7 10 1
    output
    cbcaaaabdd
    input
    10 1
    agjucbvdfk
    1 10 1
    output
    abcdfgjkuv
    Note
    First sample test explanation:
    题意,给一段字符串。然后一系列改动i,j之间的字符串从小到大排序,或从大到小排序。维护26的线段树。i,j改动。仅仅须要查询一个a - z的个数,按计数排序的原理,更新一下线段树就能够了。总的复杂度为o(26 * q * log(n));速度有点慢,用伸展树应该快些。由于是成段更新,所以要用延时标记,记-1不更新,0全置0,1全置1,仅仅有这点小技巧就能够了。

    #define N 100005
    #define M 100005
    #define maxn 205
    #define SZ 26
    #define MOD 1000000000000000007
    #define lson (now<<1)
    #define rson (now<<1|1)
    int n,q,ss,ee,k,num[SZ];
    char str[N];
    struct node{
        int c,sum,l,r;
    };
    node tree[SZ][N*4];
    void pushDown(int tn,int now){
        if(tree[tn][now].c != -1){
            tree[tn][lson].c = tree[tn][rson].c = tree[tn][now].c;
            tree[tn][lson].sum = tree[tn][lson].c*(tree[tn][lson].r-tree[tn][lson].l + 1);
            tree[tn][rson].sum = tree[tn][rson].c*(tree[tn][rson].r-tree[tn][rson].l + 1);
            tree[tn][now].c = -1;
        }
    }
    void pushUp(int tn,int now){
        tree[tn][now].sum = tree[tn][lson].sum + tree[tn][rson].sum ;
    }
    void buildTree(int l,int r,int now){
        FI(SZ)
            tree[i][now].c = -1,tree[i][now].l = l,tree[i][now].r = r,tree[i][now].sum = 0;
        if(l >= r){
            return ;
        }
        int mid = (l+r)>>1;
        buildTree(l,mid,lson);
        buildTree(mid+1,r,rson);
    }
    void updateTree(int l,int r,int now,int s,int e,int tn,int c){
        if(s <= l && e>= r){
            tree[tn][now].c = c;
            tree[tn][now].sum = tree[tn][now].c*(tree[tn][now].r - tree[tn][now].l + 1);
            return ;
        }
        pushDown(tn,now);
        int mid = (l+r)>>1;
        if(s <= mid) updateTree(l,mid,lson,s,e,tn,c);
        if(e > mid) updateTree(mid+1,r,rson,s,e,tn,c);
        pushUp(tn,now);
    }
    int queryTree(int l,int r,int now,int s,int e,int tn){
        if(s <= l && e>= r){
            return tree[tn][now].sum;
        }
        pushDown(tn,now);
        int mid = (l+r)>>1;
        int ans = 0;
        if(s <= mid) ans += queryTree(l,mid,lson,s,e,tn);
        if(e > mid) ans += queryTree(mid+1,r,rson,s,e,tn);
        pushUp(tn,now);
        return ans;
    }
    void outputStr(){
         FI(n){
            FJ(SZ){
                if(queryTree(1,n,1,i+1,i+1,j)){
                    printf("%c",j+'a');
                    break;
                }
            }
        }
        printf("
    ");
    }
    int main()
    {
        while(S2(n,q)!=EOF)
        {
            SS(str);
            buildTree(1,n,1);
            FI(n){
                updateTree(1,n,1,i+1,i+1,str[i] - 'a',1);
            }
            FI(q){
                S2(ss,ee);S(k);
                FJ(SZ)
                    num[j] = queryTree(1,n,1,ss,ee,j);
                FJ(SZ)
                    updateTree(1,n,1,ss,ee,j,0);
                if(k){
                    int sum = 0;
                    FJ(SZ){
                        if(num[j])
                            updateTree(1,n,1,ss + sum,ss + sum + num[j] - 1,j,1);
                        sum += num[j];
                    }
                }
                else {
                    int sum = 0;
                    for(int j = SZ - 1;j>=0;j--){
                        if(num[j])
                            updateTree(1,n,1,ss + sum,ss + sum + num[j] - 1,j,1);
                        sum += num[j];
                    }
                }
            }
            outputStr();
        }
        return 0;
    }
    
  • 相关阅读:
    PNG 格式小图标的 CSS 任意颜色赋色技术
    CSS导航栏下划线跟随效果
    canvas 画表格、填数据、连线、拖拽、鼠标滚轮缩放
    【IE浏览器】GET请求防止读取缓存数据的解决方法
    JavaWeb——使用JavaBean
    数字签名——确保数据来源的可认证(鉴别)性和数据发送行为的不可否认性
    信息完整性验证技术——散列函数提供的消息认证技术
    OSI安全体系结构
    (持续更新)JavaScript
    (持续更新)SVN使用总结
  • 原文地址:https://www.cnblogs.com/llguanli/p/8384007.html
Copyright © 2020-2023  润新知