P2787 语文1(chin1)- 理理思维
第一眼似乎不可做,发现是字符,只有\(26\)个字母,暴力做一下就行
对于排序,查询每个字母出现次数,再区间一块一块放进去
My complete code
include
include
include
include
using namespace std;
typedef long long LL;
const LL maxn=300000;
inline LL Read(){
LL x=0,f=1; char c=getchar();
while(c<'0'||c>'9'){
if(c'-') f=-1; c=getchar();
}
while(c>='0'&&c<='9'){
x=(x<<3)+(x<<1)+c-'0'; c=getchar();
}return x*f;
}
struct node{
LL c[26],son[2],lazy;
}tree[maxn];
LL n,m,nod,root;
LL a[maxn],sum[30];
inline LL Get(char c){
return (c>='a'&&c<='z')?c-'a':c-'A';
}
inline void Update(LL now){
LL l=tree[now].son[0],r=tree[now].son[1];
for(LL i=0;i<26;++i)
tree[now].c[i]=tree[l].c[i]+tree[r].c[i];
}
inline void Pushdown(LL now,LL len1,LL len2){
if(tree[now].lazy!=-1){
LL l=tree[now].son[0],r=tree[now].son[1],c=tree[now].lazy;
tree[l].lazy=c; memset(tree[l].c,0,sizeof(tree[l].c)); tree[l].c[c]=len1;
tree[r].lazy=c; memset(tree[r].c,0,sizeof(tree[r].c)); tree[r].c[c]=len2;
tree[now].lazy=-1;
}
}
void Build(LL &now,LL l,LL r){
now=++nod;
tree[now].lazy=-1;
if(lr){
++tree[now].c[a[l]];
return;
}
LL mid=(l+r)>>1;
Build(tree[now].son[0],l,mid);
Build(tree[now].son[1],mid+1,r);
Update(now);
}
LL Query(LL now,LL l,LL r,LL lt,LL rt,LL c){
if(lt<=l&&rt>=r)
return tree[now].c[c];
LL mid=(l+r)>>1,num=0;
Pushdown(now,mid-l+1,r-mid);
if(lt<=mid)
num+=Query(tree[now].son[0],l,mid,lt,rt,c);
if(rt>mid)
num+=Query(tree[now].son[1],mid+1,r,lt,rt,c);
return num;
}
void Add(LL now,LL l,LL r,LL lt,LL rt,LL c){
if(lt>rt)
return;
if(lt<=l&&rt>=r){
for(LL i=0;i<26;++i)
tree[now].c[i]=0;
tree[now].c[c]=(r-l+1);
tree[now].lazy=c;
//Update(now);
return;
}
LL mid=(l+r)>>1;
Pushdown(now,mid-l+1,r-mid);
if(lt<=mid)
Add(tree[now].son[0],l,mid,lt,rt,c);
if(rt>mid)
Add(tree[now].son[1],mid+1,r,lt,rt,c);
Update(now);
}
void Print(LL now,LL l,LL r){
if(!now)
return;
LL mid=(l+r)>>1;
printf("%lld(%lld,%lld):",now,l,r);
for(LL i=0;i<26;++i)
printf("%lld",tree[now].c[i]);printf("\n");
Print(tree[now].son[0],l,mid);
Print(tree[now].son[1],mid+1,r);
}
char s[maxn];
int main(){
//freopen("testdata (1).in","r",stdin);
//freopen("write.out","w",stdout);
scanf("%lld%lld",&n,&m);
scanf(" %s",s+1);
for(LL i=1;i<=n;++i)
a[i]=Get(s[i]);
Build(root,1,n);
while(m--){
LL op,l,r;
scanf("%lld%lld%lld",&op,&l,&r);
char c;
if(op1){
scanf(" %c",&c);
printf("%lld\n",Query(root,1,n,l,r,Get(c)));
}else if(op2){
scanf(" %c",&c);
Add(root,1,n,l,r,Get(c));
}else{
for(LL i=1;i<=26;++i)
sum[i]=sum[i-1]+Query(root,1,n,l,r,i-1);
for(LL i=1;i<=26;++i)
Add(root,1,n,l+sum[i-1],l+sum[i]-1,i-1);
}
//
}
return 0;
}/*
操作1: 1 xi yi ki 表示将第xi到第yi个字符中ki出现的次数输出
操作2: 2 xi yi ki 表示将第xi到第yi个字符全部替换为ki
操作3: 3 xi yi 表示将第xi到第yi个字符按照A-Z的顺序排序
8 10
cbBCaBbA
1 1 7 A
3 1 3
2 2 7 b
2 1 7 c
1 2 2 c
*/