社区讨论

求调

P4119[Ynoi2018] 未来日记参与者 1已保存回复 0

讨论操作

快速查看讨论及其快照的属性,并进行相关操作。

当前回复
0 条
当前快照
1 份
快照标识符
@mhizot8h
此快照首次捕获于
2025/11/03 18:20
4 个月前
此快照最后确认于
2025/11/03 18:20
4 个月前
查看原帖
CPP
#include<bits/stdc++.h>
#define gc pa == pb && (pb = (pa = buf) + fread(buf, 1, 100000, stdin), pa == pb) ? EOF : *pa++
#define rd read()
#define md 998244353
#define N 2005
#define V 2000
#define inf LONG_LONG_MAX 
using namespace std;
static char buf[100000], * pa(buf), * pb(buf);
const int block=2,S=N/block+5,vt=(V-1)/block+1;
int n,m,bl[N],L[S],R[S],a[N],tot;
inline int read(){
	register int x=0,ss=1,s=gc;
	while(!isdigit(s)&&s!='-')s=gc;
	if(s=='-')ss=-1,s=gc;
	while(isdigit(s))x=(x<<1)+(x<<3)+(s^48),s=gc;
	return ss*x;
}
int rt[S][N],fa[N];
inline int find(int x){return fa[x]==x?x:fa[x]=find(fa[x]);}
inline void merge(int x,int y){fa[find(x)]=find(y);}
int cnt[S][N],pcnt[S][N],bcnt[S][N];
inline int get(int x){return a[find(rt[bl[x]][a[x]])];}
inline void pushdown(int x){
	for(int i=L[x];i<=R[x];i++) a[i]=get(i);
}
inline void build(int x){
	for(int i=L[x];i<=R[x];i++) rt[x][a[i]]=i;
	for(int i=L[x];i<=R[x];i++) fa[i]=rt[x][a[i]];
}
inline void modify(int l,int r,int x,int y){
	if(x==y) return;
	int cx=0,cy=0;
	if(bl[l]==bl[r]){
		pushdown(bl[l]);
		for(int i=l;i<=r;i++){
			if(a[i]==x) cnt[bl[l]][x]--,cnt[bl[l]][y]++,cx--,cy++,a[i]=y;
		} 
		build(bl[l]);
		for(int i=bl[r];i<=tot;i++){pcnt[i][x]+=cx;pcnt[i][y]+=cy;bcnt[i][bl[x]]+=cx;bcnt[i][bl[y]]+=cy;}
		return;
	}
	pushdown(bl[l]);
	for(int i=l;i<=R[bl[l]];i++){
		if(a[i]==x) pcnt[bl[l]][x]--,pcnt[bl[l]][y]++,bcnt[bl[l]][bl[x]]--,bcnt[bl[l]][bl[y]]++,cnt[bl[l]][x]--,cnt[bl[l]][y]++,cx--,cy++,a[i]=y;
	} 
	build(bl[l]);
	for(int i=bl[l]+1;i<bl[r];i++){
		if(cnt[i][x]){                                                    
			if(cnt[i][y]) merge(rt[i][x],rt[i][y]);                                                                                                                                                                                                       
			else rt[i][y]=rt[i][x],a[rt[i][x]]=y;			                                                              
		}
		cx-=cnt[i][x];cy+=cnt[i][x];cnt[i][y]+=cnt[i][x];cnt[i][x]=0;
		pcnt[i][x]+=cx;pcnt[i][y]+=cy;bcnt[i][bl[x]]+=cx;bcnt[i][bl[y]]+=cy;
	}
	pushdown(bl[r]);
	for(int i=L[bl[r]];i<=r;i++){
		if(a[i]==x) cnt[bl[r]][x]--,cnt[bl[r]][y]++,cx--,cy++,a[i]=y;
	} 
	build(bl[r]);
	for(int i=bl[r];i<=tot;i++){pcnt[i][x]+=cx;pcnt[i][y]+=cy;bcnt[i][bl[x]]+=cx;bcnt[i][bl[y]]+=cy;}
}
int scnt[N],sbcnt[S];
inline int getb(int l,int r,int x){if(l<=r) return bcnt[r][x]-bcnt[l][x];return 0;}
inline int getp(int l,int r,int x){if(l<=r) return pcnt[r][x]-pcnt[l][x];return 0;}
inline void clear(int l,int r){
	if(bl[l]==bl[r]){                               
		for(int i=l;i<=r;i++) scnt[a[i]]--,sbcnt[bl[a[i]]]--;
	}
	else{
		for(int i=l;i<=R[bl[l]];i++) scnt[a[i]]--,sbcnt[bl[a[i]]]--;
		for(int i=L[bl[r]];i<=r;i++) scnt[a[i]]--,sbcnt[bl[a[i]]]--;
	}
}
inline int ask(int l,int r,int k){
	if(bl[l]==bl[r]){                               
		pushdown(bl[l]);
		for(int i=l;i<=r;i++) scnt[a[i]]++,sbcnt[bl[a[i]]]++;
		build(bl[l]);
	}
	else{
		pushdown(bl[l]);pushdown(bl[r]);
		for(int i=l;i<=R[bl[l]];i++) scnt[a[i]]++,sbcnt[bl[a[i]]]++;
		for(int i=L[bl[r]];i<=r;i++) scnt[a[i]]++,sbcnt[bl[a[i]]]++;
		build(bl[l]);build(bl[r]);
	}
	int kl=bl[l],kr=bl[r]-1;
	for(int i=1;i<=bl[V];i++){
		if(getb(kl,kr,i)+sbcnt[i]<k) k-=getb(kl,kr,i)+sbcnt[i];
		else{
			for(int j=(i-1)*block+1;;j++){
				if(getp(kl,kr,j)+scnt[j]<k) k-=getp(kl,kr,j)+scnt[j];
				else{clear(l,r);return j;}
			}
		}
	}
}
inline void init(){
	for(int i=1;i<=V;i++) bl[i]=(i-1)/block+1;
	tot=bl[n];
	for(int i=1;i<=tot;i++){
		L[i]=R[i-1]+1,R[i]=min(i*block,n);build(i);
		for(int j=L[i];j<=R[i];j++){pcnt[i][a[j]]++;cnt[i][a[j]]++;bcnt[i][bl[a[j]]]++;}
		for(int j=1;j<=V;j++) pcnt[i][j]+=pcnt[i-1][j];
		for(int j=1;j<=vt;j++) bcnt[i][j]+=bcnt[i-1][j];
	}
}
signed main(){
//	freopen("dat.in","r",stdin);
//	freopen("outb.out","w",stdout);
//	cout<<1;
	n=rd;m=rd;
	for(int i=1;i<=n;i++) a[i]=rd;
	init();
	for(int i=1,op,l,r,x,y;i<=m;i++){
		op=rd,l=rd,r=rd,x=rd;
		if(op==1) modify(l,r,x,rd);
		else cout<<ask(l,r,x)<<'\n';
		for(int j=1;j<=n;j++) cout<<get(j)<<' ';cout<<'\n';
	}
	return 0;
}
/*
5 1
1 1 1 4 5
1 1 2 1 5
*/
求调,6,7 wa,4,8,9 Tle

回复

0 条回复,欢迎继续交流。

正在加载回复...