P2787 语文1(chin1)- 理理思维

P2787 语文1(chin1)- 理理思维

1.获取第x到第y个字符中字母k出现了多少次

2.将第x到第y个字符全部赋值为字母k

3.将第x到第y个字符按照A-Z的顺序排序


读字符串我再单个单个读我吃素(shi)好了


Solution

考前练线段树
字母不多, 开26个线段树即可
操作一直接查询
操作二给定颜色全部涂色, 其他全部去色
操作三先记录此区间有什么颜色, 在分别赋值即可

Code

#include<iostream>
#include<cstdio>
#include<queue>
#include<cstring>
#include<algorithm>
#include<climits>
#include<ctype.h>
#define LL long long
#define REP(i, x, y) for(int i = (x);i <= (y);i++)
using namespace std;
int RD(){
    int out = 0,flag = 1;char c = getchar();
    while(c < '0' || c >'9'){if(c == '-')flag = -1;c = getchar();}
    while(c >= '0' && c <= '9'){out = out * 10 + c - '0';c = getchar();}
    return flag * out;
    }
const int maxn = 200019;
int num, na;
int v[maxn][26];//初始位置
#define lid (id << 1)
#define rid (id << 1) | 1
struct Seg_tree{
	int l, r;
	int sum, lazy;
	}tree[maxn << 2][26];
void pushup(int id, int o){tree[id][o].sum = tree[lid][o].sum + tree[rid][o].sum;}
void build(int id, int l, int r, int o){
	tree[id][o].l = l, tree[id][o].r = r, tree[id][o].lazy = -1;
	if(l == r){
		tree[id][o].sum = v[l][o];
		return ;
		}
	int mid = (tree[id][o].l + tree[id][o].r) >> 1;
	build(lid, l, mid, o), build(rid, mid + 1, r, o);
	pushup(id, o);
	}
void pushdown(int id, int o){
	if(tree[id][o].lazy != -1){//涂或者不涂,直接覆盖
		int val = tree[id][o].lazy;
		tree[lid][o].sum = (tree[lid][o].r - tree[lid][o].l + 1) * val;
		tree[rid][o].sum = (tree[rid][o].r - tree[rid][o].l + 1) * val;
		tree[lid][o].lazy = val;
		tree[rid][o].lazy = val;
		tree[id][o].lazy = -1;
		}
	}
void update(int id, int val, int l, int r, int o){
	pushdown(id, o);
	if(tree[id][o].l == l && tree[id][o].r == r){
		tree[id][o].sum = (tree[id][o].r - tree[id][o].l + 1) * val;
		tree[id][o].lazy = val;
		return ;
		}
	int mid = (tree[id][o].l + tree[id][o].r) >> 1;
	if(mid < l)update(rid, val, l, r, o);
	else if(mid >= r)update(lid, val, l, r, o);
	else update(lid, val, l, mid, o), update(rid, val, mid + 1, r, o);
	pushup(id, o);
	}
int query(int id, int l, int r, int o){
	pushdown(id, o);
	if(tree[id][o].l == l && tree[id][o].r == r)return tree[id][o].sum;
	int mid = (tree[id][o].l + tree[id][o].r) >> 1;
	if(mid < l)return query(rid, l, r, o);
	else if(mid >= r)return query(lid, l, r, o);
	else return query(lid, l, mid, o) + query(rid, mid + 1, r, o);
	}
char s;
void work1(){
	int l = RD(), r = RD();
	scanf("%c", &s);
	s = toupper(s);
	printf("%d\n", query(1, l, r, s - 'A'));
	//puts("");puts("");puts("");
	}
void work2(){
	int l = RD(), r = RD();
	scanf("%c", &s);
	s = toupper(s);
	REP(i, 0, 25){
		if(i == s - 'A')update(1, 1, l, r, i);
		else update(1, 0, l, r, i);
		}
	}
int ton[26];
void work3(){
	int l = RD(), r = RD();
	REP(i, 0, 25)ton[i] = query(1, l, r, i), update(1, 0, l, r, i);
	REP(i, 0, 25){
		if(ton[i] == 0)continue;
		update(1, 1, l, l + ton[i] - 1, i);
		l += ton[i];
		}
	}
char ss[maxn];
int main(){
	num = RD(), na = RD();
	
	scanf("%s", ss);
	REP(i, 0, num - 1){
		char now = ss[i];
		int c = toupper(now) - 'A';
		v[i + 1][c] = 1;
		}
	REP(i, 0, 25)build(1, 1, num, i);
	while(na--){
		int cmd = RD();
		if(cmd == 1)work1();
		else if(cmd == 2)work2();
		else work3();
		}
	return 0;
	}
posted @ 2018-10-19 22:08  Tony_Double_Sky  阅读(182)  评论(0编辑  收藏  举报