社区讨论

萌新分块RE求助

P5385[Cnoi2019] 须臾幻境参与者 13已保存回复 24

讨论操作

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

当前回复
24 条
当前快照
1 份
快照标识符
@mi86bpsh
此快照首次捕获于
2025/11/21 09:20
4 个月前
此快照最后确认于
2025/11/21 10:00
4 个月前
查看原帖
经检查,LCT没锅,分块不知道为什么就RE了qaq
CPP
#include<cstdio>
#include<iostream>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<vector>
#define N 300003
#define ll long long
#define reg register
#define ls son[u][0]
#define rs son[u][1]
#define inf 0x3f3f3f3f
using namespace std;

struct edge{
	int u,v;
	edge(int u=0,int v=0):u(u),v(v){}
}e[N];

int f[N],a[N],uf[N],be[N],bl[N],br[N];
int cnt[451][200003];
int n,m,q,t,unit;

inline void read(int &x);
void print(int x);

struct Link_Cut_Tree{
	int son[N][2],fa[N],st[N];
	int rev[N],minn[N];
	
	inline bool notroot(int u){
		return son[fa[u]][0]==u||son[fa[u]][1]==u;
	}
	
	inline void pushup(int u){
		minn[u] = u;
		if(ls&&a[minn[ls]]<a[minn[u]]) minn[u] = minn[ls];
		if(rs&&a[minn[rs]]<a[minn[u]]) minn[u] = minn[rs];
	}
	
	inline void pushr(int u){
		swap(ls,rs);
		rev[u] ^= 1;
	}
	
	inline void pushdown(int u){
		if(!rev[u]) return;
		if(ls) pushr(ls);
		if(rs) pushr(rs);
		rev[u] = 0;
	}
	
	inline void rotate(int x){
		int y = fa[x],z = fa[y];
		int k = son[y][1]==x,w = son[x][k^1];
		if(notroot(y)) son[z][son[z][1]==y] = x;
		son[x][k^1] = y;
		son[y][k] = w;
		if(w) fa[w] = y;
		fa[y] = x,fa[x] = z;
		pushup(y);
	}
	
	inline void splay(int x){
		int y = x,z = 0;
		st[++z] = y;
		while(notroot(y)) st[++z] = y = fa[y];
		while(z) pushdown(st[z--]);
		while(notroot(x)){
			y = fa[x],z = fa[y];
			if(notroot(y)){
				if((son[z][1]==y)==(son[y][1]==x)) rotate(y);
				else rotate(x);
			}
			rotate(x);
		}
		pushup(x);
	}
	
	inline void access(int u){
		for(reg int y=0;u;u=fa[u]){
			splay(u);
			rs = y;
			pushup(u);
			y = u;
		}
	}
	
	inline void makeroot(int u){
		access(u),splay(u);
		pushr(u);
	}
	
	inline void split(int u,int v){
		makeroot(u);
		access(v),splay(v);
	}
	
	inline void link(int u,int v){
		makeroot(u);
		fa[u] = v;
	}
	
	inline void cut(int u,int v){
		split(u,v);
		son[v][0] = fa[u] = 0;
		pushup(v);
	}
	
	inline int query(int u,int v){
		split(u,v);
		return minn[v];
	}
}T;

inline int find(int x){
	while(x!=uf[x]) x = uf[x] = uf[uf[x]];
	return x;
}

inline int query(int l,int r,int k){
	if(k<1) return 0;
	int res = 0;
	if(be[r]-be[l]<2){
		for(reg int i=l;i<=r;++i) res += f[i]<k;
		return res;
	}
	for(reg int i=l;i<=br[l];++i) res += f[i]<k;
	for(reg int i=be[l]+1;i<be[r];++i) res += cnt[i][k-1];
	for(reg int i=bl[r];i<=r;++i) res += f[i]<k;
	return res;
}

int main(){
	int u,v,w,l,r,key = 0;
	read(n),read(m),read(q),read(t);
	for(reg int i=1;i<=n;++i) a[i] = inf;
	for(reg int i=1;i<=m;++i) a[i+n] = i;
	for(reg int i=1;i<=n+m;++i) uf[i] = T.minn[i] = i;
	for(reg int i=1;i<=m;++i){
		read(u),read(v);
		if(u==v){
			f[i] = inf;
			continue;
		}
		e[i] = edge(u,v);
		if(find(u)==find(v)){
			w = T.query(u,v);
			T.cut(w,e[w-n].u);
			T.cut(w,e[w-n].v);
			f[i] = w-n;
		}else uf[find(u)] = find(v);
		T.link(u,n+i),T.link(v,n+i);
	}
	unit = sqrt(m)+1;
	for(reg int i=1;i<=m;++i){
		be[i] = i/unit+1;
		cnt[be[i]][f[i]]++;
		if(be[i]==be[i-1]) bl[i] = bl[i-1];
		else bl[i] = i;
	}
	for(reg int i=m;i>=1;--i){
		if(be[i]==be[i+1]) br[i] = br[i+1];
		else br[i] = i;
	}
	w = m/unit+1;
	for(reg int i=1;i<=w;++i){
		for(reg int j=1;j<=m;++j)
			cnt[i][j] += cnt[i][j-1];
	}
	while(q--){
		read(l),read(r);
		if(t==1){
			l = (l+key)%m+1;
			r = (r+key)%m+1;
		}
		if(l>r) swap(l,r);
		key = n-query(l,r,l);	
		print(key),putchar('\n');
	}
	return 0;
}

inline void read(int &x){
    x = 0;
    char c = getchar();
    while(c<'0'||c>'9') c = getchar();
    while(c>='0'&&c<='9'){
        x = (x<<3)+(x<<1)+(c^48);
        c = getchar();
    }
}

void print(int x){
    if(x>9) print(x/10);
    putchar(x%10+'0');
}

回复

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

正在加载回复...