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;
}