求助分块
查看原帖
求助分块
333855
int233楼主2023/7/29 15:12

RT

写的是类似数列分块入门 6的分块解法,貌似有插入就会寄。

求调

Code:

#include<iostream>
#include<cmath>
#include<cstdio> 
#include<vector>
#include<algorithm>
#define int ull
using namespace std;
typedef unsigned long long ll;
typedef long long ull;
typedef pair<ull,ull> pr;
const ll jz=1e9+7;
struct node{
	ll val;
	int sz;
}hs[405];
string s;
int blo,n,m,l,r,mid;
string opt,tmp;
ll pows[100005];
ull ms,x,d,c[100005],cnt,N;
vector<ll> vc[405];
node merge(node x,node y){
	node ret;
	ret.val=x.val*pows[y.sz]+y.val;
	ret.sz=x.sz+y.sz;
	return ret;
}
node mknode(ll x){
	node ret;
	ret.sz=1;
	ret.val=x;
	return ret;
}
void gethash(int x){
	if(vc[x].empty()){
		return ;
	}
	node ret=mknode(vc[x][0]);
	for(int i=1;i<(ull)vc[x].size();i++){
		ret=merge(ret,mknode(vc[x][i]));
	}
	hs[x]=ret;
}
pr qry(ull x){
	int k=1ll;
	while(x>(ull)vc[k].size()){
		x-=vc[k].size();
		k++;
	}
	return {k,x-1};
}
void change(){
	N=0;
	for(int i=1;i<=ms;i++){
		for(int j=0;j<(ull)vc[i].size();j++){
			c[++N]=vc[i][j];
		}
		vc[i].clear();
	}
}
void rebuild(int f){
	if(f){
		change();
	}
	blo=int(sqrt(N));
	for(int i=1;i<=N;i++){
		vc[(i-1)/blo+1].push_back(c[i]);
	}
	ms=(N-1)/blo+1;
	for(int i=1;i<=ms;i++){
		gethash(i);
	}
}
void ins(){
	N++;
	if(!x){
		reverse(vc[1].begin(),vc[1].end());
		vc[1].push_back(d);
		reverse(vc[1].begin(),vc[1].end());
		gethash(1);
		if((ull)vc[1].size()>7*ms){
			rebuild(1);
		}
		return ;
	}
	pr ts=qry(x);
	vc[ts.first].insert(vc[ts.first].begin()+ts.second,d);
	gethash(ts.first);
	if((ull)vc[ts.first].size()>7*ms){
		rebuild(1);
	}
}
void modify(){
	pr ts=qry(x);
	vc[ts.first][ts.second]=d;
	gethash(ts.first);
}
node gethasher(ull l,ull r){
	node ret;
	ret.val=ret.sz=0;
	if(r-l==-1){
		return ret;
	}
	pr ts=qry(l),ts2=qry(r);
	ret=mknode(vc[ts.first][ts.second]);
	if(ts.first==ts2.first){
		for(int i=ts.second+1;i<=ts2.second;i++){
			ret=merge(ret,mknode(vc[ts.first][i]));
		}
		return ret;
	}
	for(int i=ts.second+1;i<(ull)vc[ts.first].size();i++){
		ret=merge(ret,mknode(vc[ts.first][i]));
	}
	for(int i=ts.first+1;i<ts2.first;i++){
		ret=merge(ret,hs[i]);
	}
	for(int i=0;i<=ts2.second;i++){
		ret=merge(ret,mknode(vc[ts2.first][i]));
	}
	return ret;
}
signed main(){
	//freopen("9.in","r",stdin);
	//freopen("9.out","w",stdout);
	cin>>s;
	cnt=N=n=s.length();
	pows[0]=1ll;
	for(int i=1;i<=100000;i++){
		pows[i]=pows[i-1ll]*jz;
	}
	for(int i=1;i<=n;i++){
		c[i]=s[i-1ll]-'a'+1ll;
	}
	rebuild(0);
	cin>>m;
	for(int i=1;i<=m;i++){
		cin>>opt;
		if(opt=="Q"){
			cin>>x>>d;
			l=0;
			r=min(cnt-x+1,cnt-d+1);
			while(l<r){
				mid=(l+r+1ll)>>1ll;
				if(gethasher(x,x+mid-1ll).val==gethasher(d,d+mid-1ll).val){
					l=mid;
				}
				else{
					r=mid-1ll;
				}
			}
			cout<<l<<endl;
		}
		if(opt=="R"){
			cin>>x>>tmp;
			d=tmp[0]-'a'+1ll;
			modify();
		}
		if(opt=="I"){
			cnt++;
			cin>>x>>tmp;
			d=tmp[0]-'a'+1ll;
			ins();
		//	cout<<vc[qry(28101).first][qry(28101).second]<<endl; 
		}
	}
	return 0;
} 
2023/7/29 15:12
加载中...