卡常求助
查看原帖
卡常求助
758680
hzy_____楼主2023/11/2 21:22

操作分块+序列分块

#include<bits/stdc++.h>
#define ll long long
#define endl '\n'
#define fc(x) (1ll*(x)*((x)+1)/2)
namespace io{
    const ll BUFSIZE=1<<22;
    char ibuf[BUFSIZE],*is=ibuf,*it=ibuf;
    char obuf[BUFSIZE],*os=obuf,*ot=obuf+BUFSIZE;
    inline char getch(){
        if(is==it)it=(is=ibuf)+fread(ibuf,1,BUFSIZE,stdin);
        return (is==it)?EOF:*is++;
    }
    inline ll read(){
        ll res=0;bool neg=false;char ch=getch();
        while(!(isdigit(ch)||ch=='-')&&ch!=EOF)ch=getch();
        if(ch=='-')neg=true,ch=getch();
        while(isdigit(ch))res=res*10+(ch-'0'),ch=getch();
        return neg?-res:res;
    }
    inline void flush(){
        fwrite(obuf,1,os-obuf,stdout);
        os=obuf;
    }
    inline void putch(char ch){
        *os++=ch;
        if(os==ot)flush();
    }
    inline void write(ll res){
        char q[25];ll top;
        if(res<0)putch('-'),res=-res;
        if(res==0)putch('0');           
        top=0;
        while(res)q[top++]=res%10+'0',res/=10;
        while(top--)putch(q[top]);
    }
}
using namespace io;
using namespace std;
const int N=3e5+10;
int sum[N],n,m,op,l,r,x,y,a[N],bl,tot,c[N],st[N],ed[N],pos[N],S,tot1,tot2,tq1,tq2;
ll ans[N];
bitset<N> b,vis,bb,bbb;
vector<int> tg[N];
struct que{int l,r,x,t;}q1[N],q2[N];
bool cmp(que a,que b){return a.x<b.x;}
pair<int,int> v1[N*3],v2[N*3];
void init(){
	bl=sqrt(n*3/4),tot=(n-1)/bl+1;
	for(int i=1;i<=n;i++)pos[i]=(i-1)/bl+1;
	for(int i=1;i<=tot;i++)st[i]=(i-1)*bl+1,ed[i]=i*bl;
	ed[tot]=n;
}
void revoke(){
	reverse(v1+1,v1+tot1+1);
	for(int i=1;i<=tot1;i++)c[v1[i].first]=v1[i].second;
	for(int i=1;i<=tot2;i++)sum[v2[i].first]-=v2[i].second;
	tot1=tot2=0;
}
void do1(int x,int k){
	int y=0;
	v1[++tot1]={x,c[x]};
	v1[++tot1]={c[x+1],c[c[x+1]]};
	y-=fc(c[x+1]-x);
	int r=c[x+1],l=x;
	c[l]=r;
	c[r]=l;
	y+=fc(r-l+1);
	sum[k]+=y;
	v2[++tot2]={k,y};
} 
void do2(int x,int k){
	int y=0;
	v1[++tot1]={x,c[x]};
	v1[++tot1]={c[x-1],c[c[x-1]]};
	y-=fc(x-c[x-1]);
	int r=x,l=c[x-1];
	c[l]=r;
	c[r]=l;
	y+=fc(r-l+1);
	sum[k]+=y;
	v2[++tot2]={k,y};
}
void do3(int x,int k){
	v1[++tot1]={x,c[x]};
	c[x]=x;
	sum[k]++;
	v2[++tot2]={k,1};
}
void do4(int x,int k){
	int y=0;
	v1[++tot1]={c[x+1],c[c[x+1]]};
	v1[++tot1]={c[x-1],c[c[x-1]]};
	v1[++tot1]={x,c[x]};
	y-=fc(x-c[x-1]);
	y-=fc(c[x+1]-x);
	int r=c[x+1],l=c[x-1];
	c[r]=l;
	c[l]=r;
	c[x]=x;
	y+=fc(r-l+1);
	sum[k]+=y;
	v2[++tot2]={k,y};
}
void turn(int x){
	int k=pos[x];
	if(x==st[k]){
		if(c[x+1])do1(x,k);
		else do3(x,k);
	}else if(x==ed[k]){
		if(c[x-1])do2(x,k);
		else do3(x,k);
	}else{
		if(c[x+1]&&c[x-1])do4(x,k);
		else if(c[x+1])do1(x,k);
		else if(c[x-1])do2(x,k);
		else do3(x,k);
	}
}
int get(int l,int r){
	int ans=0;
	for(int i=l;i<=r;i++){
		if(!c[i])continue;
		int j=i;
		while(j<=r&&c[j])j++;
		ans+=fc(j-i);
		i=j-1;
	}
	return ans;
}
ll ask(int l,int r){
	int L=pos[l],R=pos[r];
	ll ans=0;
	if(L==R)ans=get(l,r);
	else{
		int last=max(l,c[ed[L]]?c[ed[L]]:ed[L]+1);
		ans=get(l,ed[L]);
		if(c[ed[L]])ans-=fc(ed[L]-last+1);
		for(int i=L+1;i<=R-1;i++){
			if(c[st[i]]==ed[i])continue;
			ans+=fc((c[st[i]]?c[st[i]]:ed[i-1])-last+1);
			ans+=sum[i];
			if(c[st[i]])ans-=fc(c[st[i]]-st[i]+1);
			if(c[ed[i]])ans-=fc(ed[i]-c[ed[i]]+1);
			last=c[ed[i]]?c[ed[i]]:ed[i]+1;
		}
		ans+=get(st[R],r);
		ans+=fc(min((c[st[R]]?c[st[R]]:ed[R-1]),r)-last+1);
		if(c[st[R]])ans-=fc(min(r,c[st[R]])-st[R]+1);
	}
	return ans;
}
void solve(){
	sort(q2+1,q2+tq2+1,cmp);
	reverse(q1+1,q1+tq1+1);
	for(int i=1;i<=tq1;i++)vis[q1[i].l]=true;
	for(int i=1;i<=n;i++)if(!vis[i])tg[a[i]].push_back(i);
	int j=1;
	for(int w=1;w<=tq2;w++){
		que i=q2[w];
		while(j<=i.x){
			for(int x:tg[j])turn(x);
			j++;
		}
		tot1=0,tot2=0;
		for(int o=1;o<=tq1;o++){
			que k=q1[o];
			if(k.t>i.t||bb[k.l])continue;
			bb[k.l]=true;
			if(k.r<=i.x)turn(k.l);
		}
		for(int o=1;o<=tq1;o++){
			que k=q1[o];
			if(bb[k.l]||bbb[k.l])continue;
			bbb[k.l]=true;
			if(a[k.l]<=i.x)turn(k.l);
		}
		for(int o=1;o<=tq1;o++){
			que k=q1[o];
			bbb[k.l]=bb[k.l]=false;
		}
		ans[i.t]=ask(i.l,i.r);
		revoke();
	}
	reverse(q1+1,q1+tq1+1);
	for(int i=1;i<=tq1;i++)a[q1[i].l]=q1[i].r;
	for(int i=1;i<=n;i++)tg[i].clear();
	memset(sum,0,sizeof(sum));
	memset(c,0,sizeof(c));
	vis=0,tq1=0,tq2=0;
}
signed main(){
	n=read(),m=read();
	init();
	for(int i=1;i<=n;i++)a[i]=read();
	S=sqrt(m*14);
	for(int i=1;i<=m;i++){
		op=read();
		if(op==1)x=read(),y=read(),q1[++tq1]={x,y,0,i};
		else l=read(),r=read(),x=read(),q2[++tq2]={l,r,x,i},b[i]=true;
		if(tq1+tq2==S)solve();
	}
	solve();
	for(int i=1;i<=m;i++)if(b[i])write(ans[i]),putch('\n');
	flush();
}
2023/11/2 21:22
加载中...