求助 ABC 的 F
查看原帖
求助 ABC 的 F
531930
Southern_Dynasty楼主2023/1/15 22:03

RT.

写的是分块。

#include<bits/stdc++.h>
//#pragma GCC optimize("Ofast")
#define gt getchar
#define pt putchar
#define y1 y233
typedef long long ll;
//typedef __int128 lll;
typedef unsigned long long ull;
const int N=1e5+5;
const int V=320;
using namespace std;
inline bool __(char ch){return ch>=48&&ch<=57;}
inline int read(){
   	int x=0;bool sgn=0;char ch=gt();
   	while(!__(ch)&&ch!=EOF){sgn|=(ch=='-');ch=gt();}
   	while(__(ch)){x=(x<<1)+(x<<3)+(ch-48);ch=gt();}
	return sgn?-x:x;
}
template<class T>
inline void print(T x){
	static char st[70];short top=0;
	if(x<0)pt('-');
    do{st[++top]=x>=0?(x%10+48):(-(x%10)+48),x/=10;}while(x);
    while(top)pt(st[top--]);
}
template<class T>
inline void printsp(T x){
	static char st[70];short top=0;
	if(x<0)pt('-');
    do{st[++top]=x>=0?(x%10+48):(-(x%10)+48),x/=10;}while(x);
    while(top)pt(st[top--]);pt(32);
}
template<class T>
inline void println(T x){
	static char st[70];short top=0;
	if(x<0)pt('-');
    do{st[++top]=x>=0?(x%10+48):(-(x%10)+48),x/=10;}while(x);
    while(top)pt(st[top--]);pt(10);
}
inline void put_str(string s){
	int siz=s.size();
	for(int i=0;i<siz;++i) pt(s[i]);
	printf("\n");
}
int n,q,num[30],cnt[V][30],num2[30],numb,cntb;
char lval[V],rval[V],s[N];
bool is_order[V];
inline int id(int x){return (x+numb-1)/numb;}
inline int left(int x){return (x-1)*numb+1;}
inline int right(int x){return min(n,x*numb);}
inline void init(){
	for(int i=1;i<=cntb;++i){
		is_order[i]=1;
		int l=left(i),r=right(i);
		lval[i]=s[l],rval[i]=s[r];
		for(int j=l+1;j<=r;++j){
			if(s[j]<s[j-1]){
				is_order[i]=0;
				break;
			}
		}
		for(int j=l;j<=r;++j) cnt[i][s[j]-'a'+1]++;
	}
}
inline void update(int pos,char val){
	char lst=s[pos];
	int bh=id(pos);
	s[pos]=val,num[lst-'a'+1]--,num[val-'a'+1]++;
	cnt[bh][lst-'a'+1]--,cnt[bh][lst-'a'+1]++;
	int l=left(bh),r=right(bh);
	bool flag=1;
	for(int j=l+1;j<=r;++j){
		if(s[j]<s[j-1]){
			flag=0;
			break;
		}
	}
	is_order[bh]=flag;
	if(pos==l)lval[bh]=val;
	if(pos==r)rval[bh]=val;
}
inline bool query(int l,int r){
	int L=id(l),R=id(r);
	for(int i=1;i<=26;++i) num2[i]=0;
	if(L==R){
		for(int i=l+1;i<=r;++i) if(s[i]<s[i-1])return 0;
		for(int i=l;i<=r;++i) num2[s[i]-'a'+1]++;
		for(char ch=s[l]+1;ch<s[r];++ch) if(num2[ch-'a'+1]!=num[ch-'a'+1])return 0;
		return 1;
	}
	int r1=right(L),l2=left(R);
	for(int i=l+1;i<=r1;++i) if(s[i]<s[i-1])return 0;
	for(int i=l2+1;i<=r;++i) if(s[i]<s[i-1])return 0;
	for(int pos=L+1;pos<R;++pos) if(!is_order[pos])return 0;
	for(int pos=L+1;pos<=R;++pos){
		int lstr=right(pos-1);
		if(s[lstr+1]<s[lstr])return 0;
	}
	for(int i=l;i<=r1;++i) num2[s[i]-'a'+1]++;
	for(int i=l2;i<=r;++i) num2[s[i]-'a'+1]++;
	for(int pos=L+1;pos<R;++pos) for(int t=1;t<=26;++t) num2[t]+=cnt[pos][t];
	for(char qwq=s[l]+1;qwq<s[r];++qwq) if(num2[qwq-'a'+1]!=num[qwq-'a'+1])return 0;
	return 1;
}
signed main(){
	n=read(),numb=sqrt(n);
	cntb=(n+numb-1)/numb;
	scanf("%s",s+1);
	for(int i=1;i<=n;++i) num[s[i]-'a'+1]++; 
	init();
	q=read();
	while(q--){
		int opt=read(),x,l,r;
		char c;
		if(opt==1){
			x=read();
			cin>>c;
			update(x,c);
		}else{
			l=read(),r=read();
			printf(query(l,r)?"Yes\n":"No\n");
		}
	}
	return 0;
}
2023/1/15 22:03
加载中...