ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

[DarkBZOJ3514] Codechef MARCH14 GERALD07加强版

2022-03-07 23:34:52  阅读:175  来源: 互联网

标签:return MARCH14 ty GERALD07 TT int DarkBZOJ3514 ans putchar


前言

当数据结构题考起思维。。。

题目

DarkBZOJ

讲解

总之这道题初看怎么都不可做,光是连通块个数就不太会,还区间,还强制在线?

好吧,我是想不到做法的,直接讲正解:

首先我们想连通块个数怎么算?维护树边,树边会对答案产生 \(-1\) 的贡献,初始显然为节点数 \(n\)。

按标号从小到大加边,然后如果加出一个环,那么把环上编号最小的边找出来,记为 \(pre_i\),最后询问其实是问的 \([l,r]\) 中 \(pre_i<l\) 的点有多少个,这个可以用主席树。

时间复杂度 \(O(n\log_2n)\)。

代码

//12252024832524
#include <bits/stdc++.h>
#define TT template<typename T>
using namespace std; 

typedef long long LL;
const int MAXN = 200005;
const int INF = 0x3f3f3f3f;
int n,m,q,ty,ans;

LL Read()
{
	LL x = 0,f = 1;char c = getchar();
	while(c > '9' || c < '0'){if(c == '-')f = -1;c = getchar();}
	while(c >= '0' && c <= '9'){x = (x*10) + (c^48);c = getchar();}
	return x * f;
}
TT void Put1(T x)
{
	if(x > 9) Put1(x/10);
	putchar(x%10^48);
}
TT void Put(T x,char c = -1)
{
	if(x < 0) putchar('-'),x = -x;
	Put1(x); if(c >= 0) putchar(c);
}
TT T Max(T x,T y){return x > y ? x : y;}
TT T Min(T x,T y){return x < y ? x : y;}
TT T Abs(T x){return x < 0 ? -x : x;}

#define lc t[x].ch[0]
#define rc t[x].ch[1]
int tot;
struct node{
	int ch[2],f,val,s;
	bool revtag;
}t[MAXN<<1]; 
bool ck(int x){return x == t[t[x].f].ch[1];}
void lk(int x,int fa,bool d){t[x].f = fa; if(fa) t[fa].ch[d] = x;}
bool isroot(int x){return x != t[t[x].f].ch[0] && x != t[t[x].f].ch[1];}
void rev(int x){if(!x) return; t[x].revtag ^= 1; swap(lc,rc);}
void up(int x){t[x].s = Min(t[lc].s,t[rc].s),t[x].s = Min(t[x].s,t[x].val);}
void down(int x){
	if(!t[x].revtag) return;
	rev(lc); rev(rc);
	t[x].revtag = 0;
}
void rotate(int x){
	int fa = t[x].f,d = ck(x);
	if(isroot(fa)) t[x].f = t[fa].f;
	else lk(x,t[fa].f,ck(fa));
	lk(t[x].ch[d^1],fa,d);
	lk(fa,x,d^1);
	up(fa); up(x);
}
void downtag(int x){
	if(!isroot(x)) downtag(t[x].f);
	down(x);
}
void splay(int x){
	downtag(x);
	for(int y = t[x].f;!isroot(x);rotate(x),y = t[x].f)
		if(!isroot(y)) rotate(ck(x) == ck(y) ? y : x);
}
void access(int x){
	for(int lst = 0; x ;lst = x,x = t[x].f)
		splay(x),rc = lst,up(x);
}
void makeroot(int x){
	access(x); splay(x); rev(x); 
}
int findroot(int x){
	access(x); splay(x); 
	while(lc) down(x),x = lc;
	splay(x); return x;
}
void split(int x,int y){
	makeroot(x); access(y); splay(y);
}
void link(int x,int y){
	makeroot(x); t[x].f = y;
}
void cut(int x,int y){
	makeroot(x); access(y); splay(x);
	t[y].f = rc = 0,up(x); 
}

//一道题两个数据结构,重名真的烦人 
int rt[MAXN],ch[MAXN*40][2],sum[MAXN*40],pt,lsttot;
void Add(int lst,int &x,int l,int r,int pos,int val){
	if(x <= lsttot) x = ++pt,ch[x][0] = ch[lst][0],ch[x][1] = ch[lst][1],sum[x] = sum[lst];
	sum[x] += val;
	if(l == r) return;
	int mid = (l+r) >> 1;
	if(pos <= mid) Add(ch[lst][0],ch[x][0],l,mid,pos,val);
	else Add(ch[lst][1],ch[x][1],mid+1,r,pos,val);
}
int Query(int x,int l,int r,int ql,int qr){
	if(!x) return 0;
	if(ql <= l && r <= qr) return sum[x];
	int mid = (l+r) >> 1,ret = 0;
	if(ql <= mid) ret += Query(ch[x][0],l,mid,ql,qr);
	if(mid+1 <= qr) ret += Query(ch[x][1],mid+1,r,ql,qr);
	return ret;
}

int E[MAXN][3],pre[MAXN];

int main()
{
//	freopen(".in","r",stdin);
//	freopen(".out","w",stdout);
	n = tot = Read(); m = Read(); q = Read(); ty = Read();
	for(int i = 0;i <= n;++ i) t[i].s = t[i].val = INF;
	for(int i = 1;i <= m;++ i){
		E[i][0] = Read(),E[i][1] = Read();
		if(E[i][0] == E[i][1]){
			pre[i] = i;
			continue;
		}
		E[i][2] = ++tot;
		t[tot].s = t[tot].val = i;
		if(findroot(E[i][0]) == findroot(E[i][1])){
			split(E[i][0],E[i][1]); int ID = t[E[i][1]].s;
			pre[i] = ID;
			cut(E[ID][0],E[ID][2]); cut(E[ID][1],E[ID][2]);
		}
		link(E[i][0],E[i][2]); link(E[i][1],E[i][2]);
	}
	for(int i = 1;i <= m;++ i) {
		lsttot = pt;
		Add(rt[i-1],rt[i],0,m,pre[i],1);
	}
	while(q --> 0){
		int l = Read()^(ty ? ans : 0),r = Read()^(ty ? ans : 0);
		Put(ans = n-(Query(rt[r],0,m,0,l-1)-Query(rt[l-1],0,m,0,l-1)),'\n');
	}
	return 0;
}

标签:return,MARCH14,ty,GERALD07,TT,int,DarkBZOJ3514,ans,putchar
来源: https://www.cnblogs.com/PPLPPL/p/15978615.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有