zoukankan      html  css  js  c++  java
  • Codeforces 558E A Simple Task(权值线段树)

    题目链接  A Simple Task

    题意  给出一个小写字母序列和若干操作。每个操作为对给定区间进行升序排序或降序排序。

    考虑权值线段树。

    建立26棵权值线段树。每次操作的时候先把26棵线段树上的所有在该区间内的信息清空。

    然后再通过类似计数排序的方式从左往右(或从右往左)依次塞进去。

    #include <bits/stdc++.h>
    
    using namespace std;
    
    #define rep(i, a, b)	for (int i(a); i <= (b); ++i)
    #define dec(i, a, b)	for (int i(a); i >= (b); --i)
    #define ls		i << 1
    #define	rs		i << 1 | 1
    #define lson		ls, L, mid
    #define	rson		rs, mid + 1, R
    
    
    
    typedef long long LL;
    
    const int N = 1e5 + 10;
    
    struct node{
    	int sum[2];
    	int len;
    } s[27][N * 3];
    
    int n, q;
    int a[N];
    char st[N];
    int dc[27][N * 3];
    int f[27];
    
    
    inline node update(const node &x, const node &y){
    	node ret;
    	ret.len = x.len + y.len;
    	rep(i, 0, 1) ret.sum[i] = x.sum[i] + y.sum[i];
    	return ret;
    }
    
    void build(int cnt, int i, int L, int R){
    	if (L == R){
    		int z = a[L] == cnt;
    		s[cnt][i].len = 1;
    		s[cnt][i].sum[z] = 1;
    		s[cnt][i].sum[z ^ 1] = 0;
    		dc[cnt][i] = -1;
    		return;
    	}
    
    	int mid = (L + R) >> 1;
    	build(cnt, lson);
    	build(cnt, rson);
    	s[cnt][i] = update(s[cnt][ls], s[cnt][rs]);
    	dc[cnt][i] = -1;
    }
    
    inline void paintcover(int cnt, int i, int z){
    	dc[cnt][i] = z;
    	s[cnt][i].sum[z] = s[cnt][i].len;
    	s[cnt][i].sum[z ^ 1] = 0;
    }
    
    inline void pushdown(int cnt, int i){
    	if (~dc[cnt][i]){
    		paintcover(cnt, ls, dc[cnt][i]);
    		paintcover(cnt, rs, dc[cnt][i]);
    		dc[cnt][i] = -1;
    	}
    }
    
    void cover(int cnt, int i, int L, int R, int l, int r, int z){
    	if (l <= L && R <= r){
    		paintcover(cnt, i, z);
    		return;
    	}
    
    	pushdown(cnt, i);
    	int mid = (L + R) >> 1;
    	if (l <= mid) cover(cnt, lson, l, r, z);
    	if (r >  mid) cover(cnt, rson, l, r, z);
    	s[cnt][i] = update(s[cnt][ls], s[cnt][rs]);
    }
    
    int query(int cnt, int i, int L, int R, int l, int r){
    	int ret = 0;
    	if (l <= L && R <= r) return s[cnt][i].sum[1];
    	int mid = (L + R) >> 1;
    	pushdown(cnt, i);
    	if (l <= mid) ret += query(cnt, lson, l, r);
    	if (r >  mid) ret += query(cnt, rson, l, r);
    	return ret;
    }
    
    int main(){
    
    	scanf("%d%d", &n, &q);
    	scanf("%s", st + 1);
    	rep(i, 1, n) a[i] = (int)st[i] - 96;
    	rep(i, 1, 26) build(i, 1, 1, n);
    
    	while (q--){
    		int x, y, z;
    		scanf("%d%d%d", &x, &y, &z);
    		rep(i, 1, 26) f[i] = query(i, 1, 1, n, x, y);
    		rep(i, 1, 26) cover(i, 1, 1, n, x, y, 0);
    		if (z){
    			int pos = x;
    			rep(i, 1, 26) if (f[i]){
    				cover(i, 1, 1, n, pos, pos + f[i] - 1, 1);
    				pos += f[i];
    			}
    		}
    
    		else{
    			int pos = x;
    			dec(i, 26, 1) if (f[i]){
    				cover(i, 1, 1, n, pos, pos + f[i] - 1, 1);
    				pos += f[i];
    			}
    		}
    	}
    
    	rep(i, 1, n){
    		rep(j, 1, 26) if (query(j, 1, 1, n, i, i)){
    			putchar(j + 96);
    			break;
    		}
    	}
    
    	putchar(10);
    	return 0;
    }
    

      

  • 相关阅读:
    【HCIE-RS_TAC诊断5-2】
    【HCIE-RS_TAC诊断5-1】
    【HCIE-RS_TAC诊断4】
    【HCIE-RS_TAC诊断3】
    【HCIE-RS_TAC诊断2】
    华为ICT大赛辅导——双AC主备双链路备份
    shell 函数与内置变量
    CF505E Mr. Kitayuta vs. Bamboos
    CF559E Gerald and Path
    CF538H Summer Dichotomy
  • 原文地址:https://www.cnblogs.com/cxhscst2/p/7762739.html
Copyright © 2011-2022 走看看