社区讨论

求助p3960(赏额一个关注,可能小号)

题目总版参与者 1已保存回复 0

讨论操作

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

当前回复
0 条
当前快照
1 份
快照标识符
@lo8bx51d
此快照首次捕获于
2023/10/27 16:06
2 年前
此快照最后确认于
2023/10/27 16:06
2 年前
查看原帖
rt
C
#include<bits/stdc++.h>
#define int long long 
using namespace std;
const int N=330000;
struct node{
	int size;
	int l,r,L,R;
	int w;
}tree[N];
int root[N],num;
int n,m,q;
inline int read(){
	int x=0,f=1;
	char ch=getchar();
	while(ch<'0' || ch>'9'){
		if(ch=='-') f=-1;
		ch=getchar();
	}
	while(ch>='0' && ch<='9'){
		x=(x<<1)+(x<<3)+(ch^48);
		ch=getchar();
	}
	return f*x;
}
int newnode(int x,int y){
	num++;
	tree[num].l=x,tree[num].r=y;
	tree[num].w=rand();
	tree[num].L=tree[num].R=0;
	tree[num].size=y-x+1;
	return num;
}
void update(int r){
	tree[r].size=tree[tree[r].L].size+tree[r].r-tree[r].l+1+tree[tree[r].R].size;
}
void merge(int r1,int r2,int &r){
	if(r1==0 or r2==0){
		r=r1+r2;
		return;
	}
	if(tree[r1].w<tree[r2].w){
		r=r1;
		merge(tree[r1].R,r2,tree[r].R);
	}else{
		r=r2;
		merge(r1,tree[r2].L,tree[r].L);
	}
	update(r);
}
void splitnode(int &r,int k){
	if(tree[r].r-tree[r].l+1<k)return;
	int x=tree[r].l+k-1;
	if(x+1<=tree[r].r){
		int tmp=newnode(tree[r].l,x);
		tree[tmp].L=tree[r].L;
		tree[r].l=x+1;
		tree[r].L=0;
		merge(tmp,r,r);
	}
}
void split(int r,int size,int &r1,int &r2){
	if(r==0){
		r1=r2=0;
		return;
	}
	if(size<=tree[tree[r].L].size){
		r2=r;
		split(tree[r].L,size,r1,tree[r2].L);
	}else{
		splitnode(r,size-tree[tree[r].L].size);
		r1=r;
		split(tree[r].R,size-tree[tree[r].L].size-tree[r].r+tree[r].l-1,tree[r1].R,r2);
	}
	update(r);
}
int del1(int &r,int x){
	int r1,r2,rr,rx;
	split(r,x,rr,r2);
	split(rr,x-1,r1,rx);
	merge(r1,r2,r);
	return rx;
}
void print1(int r){
	if(r==0) return;
	print1(tree[r].L);
	printf("r:%d  l:%d  r:%d  w:%d  size:%d  L:%d  R:%d\n",r,tree[r].l,tree[r].r,tree[r].w,tree[r].size,tree[r].L,tree[r].R);
	print1(tree[r].R);
}
signed main(){
	n=read();m=read();q=read();
	num=0;
	for(int i=1; i<=n; i++){
		root[i]=newnode((i-1)*m+1,i*m-1);
	}
	for(int i=1; i<=n; i++){
		int tmp=newnode(i*m,i*m); 
		merge(root[n+1],tmp,root[n+1]);
	}
	/*for(int i=1;i<=n+1;i++){
		printf("%d:\n",i);
		print1(root[i]);
		printf("\n");
	}*/
	for(int i=1; i<=q; i++){
		int x,y;
		x=read();y=read();
		if(y==m){
			int tmp=del1(root[n+1],x);
			printf("%lld\n",tree[tmp].l);
			merge(root[n+1],tmp,root[n+1]);
		}else{
			int tmp=del1(root[x],y);
			printf("%lld\n",tree[tmp].l);
			int tmp1=del1(root[n+1],x);
			merge(root[x],tmp1,root[x]);
			merge(root[n+1],tmp,root[n+1]);
		}
	}
} 

回复

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

正在加载回复...