首页 > 其他分享 >急急急,求完全正确的快读板子!!!

急急急,求完全正确的快读板子!!!

时间:2024-05-21 19:30:51浏览次数:24  
标签:rt now 急急 top define 板子 int 完全正确 rk

急急急,求完全正确的快读板子!!!

首先这其实是半篇题解。
关于染色这道题。
其实思路非常简单,只要想到树剖,之后用线段树去维护左右边界上的颜色以及区间答案即可。
只需注意pushup的时候要把左右边界颜色更新,转移时相邻区间看颜色相等就答案-1。
正解代码:

#include<bits/stdc++.h>
#define ll long long
#define qr qr()
#define pa pair<int,int>
#define fr first
#define sc second
#define lc tree[rt].ls
#define rc tree[rt].rs
using namespace std;
const int N=2e5+200;
int n,m,num[N],nd_rt[N],dep[N],son[N],nd_tot,cnt,tot,id[N],rk[N],top[N],head[N],fa[N],size[N];
struct node{
  int t,nx;
}edge[N];
struct What_can_I_say{
  int ls,rs,l,r,sum,cl,cr,lz;
}tree[N<<3];
inline int qr
{
	int x=0;char ch=getchar();bool f=0;
	while(ch>57||ch<48)
	{
		if(ch=='-')f=1;
		ch=getchar();
	}
	while(ch<=57&&ch>=48)x=(x<<3)+(x<<1)+(ch^48),ch=getchar();
	return f?-x:x;
}
void add(int f,int t)
{
	edge[++tot]={t,head[f]};
	head[f]=tot;
}
void pushup(int rt)
{
	tree[rt].cl=tree[lc].cl,tree[rt].cr=tree[rc].cr;
	tree[rt].sum=tree[lc].sum+tree[rc].sum-(tree[lc].cr==tree[rc].cl);
}
void pushdown(int rt)
{
	if(tree[rt].lz)
	{
		tree[lc].lz=tree[rt].lz;
		tree[rc].lz=tree[rt].lz;
		tree[lc].sum=1,tree[rc].sum=1;
		tree[lc].cl=tree[rt].lz,tree[lc].cr=tree[rt].lz;
		tree[rc].cl=tree[rt].lz,tree[rc].cr=tree[rt].lz;
		tree[rt].lz=0;
	}
}
void build(int &rt,int l,int r)
{
	rt=++cnt;
	tree[rt].l=l;
	tree[rt].r=r;
	if(l==r)
	{
		tree[rt].sum=1;
		tree[rt].cl=num[id[l]],tree[rt].cr=num[id[l]];
		return ;
	}
	int md=(l+r)/2;
	build(lc,l,md);
	build(rc,md+1,r);
	pushup(rt);
}
void update(int rt,int l,int r,int pos)
{
	if(tree[rt].l>=l&&tree[rt].r<=r)
	{
		tree[rt].sum=1;
		tree[rt].lz=pos;
		tree[rt].cl=pos,tree[rt].cr=pos;
		return ;
	}
	pushdown(rt);
	if(tree[lc].r>=l)update(lc,l,r,pos);
	if(tree[lc].r<r)update(rc,l,r,pos);
	pushup(rt);
}
int get_sum(int rt,int l,int r)
{
	if(tree[rt].l>=l&&tree[rt].r<=r)
	{
		// printf("(%d,%d)%d %d\n",tree[rt].l,tree[rt].r,tree[rt].cl,tree[rt].cr);
		return tree[rt].sum;
	}
	pushdown(rt);
	int ans=0;
	if(tree[lc].r>=l)ans+=get_sum(lc,l,r);
	if(tree[lc].r<r)ans+=get_sum(rc,l,r)-(ans&&tree[lc].cr==tree[rc].cl);
	pushup(rt);
	return ans;
}
int check(int rt,int st)
{
	if(tree[rt].l==tree[rt].r)
		return tree[rt].cl;
	pushdown(rt);
	if(tree[lc].r>=st)return check(lc,st);
	else return check(rc,st);
}
inline int ask(int a,int b)
{
	int ans=0,laa=0,lab=0;
	while(1)
	{
		if(dep[top[a]]<dep[top[b]])swap(a,b),swap(laa,lab);
		// printf("%d %d %d %d %d %d %d\n",get_sum(nd_rt[top[a]],rk[top[a]],rk[a]),laa,lab,a,b,f,ans);
		if(top[a]!=top[b])
		{
			ans+=get_sum(nd_rt[top[a]],rk[top[a]],rk[a])-(laa==check(nd_rt[top[a]],rk[a]));
			laa=tree[nd_rt[top[a]]].cl;
			a=fa[top[a]];
		}
		else
		{
			if(dep[a]>dep[b])swap(a,b),swap(laa,lab);
			ans+=get_sum(nd_rt[top[a]],rk[a],rk[b])-(laa==check(nd_rt[top[a]],rk[a]))-(lab==check(nd_rt[top[a]],rk[b]));
			// printf("%d %d %d %d %d %d %d\n",get_sum(nd_rt[top[a]],rk[a],rk[b]),laa,lab,a,b,f,ans);
			return ans;
		}
	}
}
inline void re(int a,int b,int pos)
{
	while(1)
	{
		if(dep[top[a]]<dep[top[b]])swap(a,b);
		if(top[a]!=top[b])
		{
			update(nd_rt[top[a]],rk[top[a]],rk[a],pos);
			a=fa[top[a]];
		}
		else
		{
			if(dep[a]>dep[b])swap(a,b);
			update(nd_rt[top[a]],rk[a],rk[b],pos);
			return ;
		}
	}
}
void get_son(int now)
{
	size[now]=1;
	for(int i=head[now];i;i=edge[i].nx)
	{
		int t=edge[i].t;
		if(t!=fa[now])
		{
			dep[t]=dep[now]+1,fa[t]=now;
			get_son(t);
			if(size[son[now]]<size[t])son[now]=t;
			size[now]+=size[t];
		}
	}
}
void dfs(int now)
{
	rk[now]=++nd_tot;
	id[nd_tot]=now;
	if(!son[now])
	{
		build(nd_rt[top[now]],rk[top[now]],rk[now]);
		return;
	}
	top[son[now]]=top[now];dfs(son[now]);
	for(int i=head[now];i;i=edge[i].nx)
	{
		int t=edge[i].t;
		if(t!=son[now]&&t!=fa[now])
		{
			top[t]=t;
			dfs(t);
		}
	}
}
void init()
{
	// n=qr,m=qr;
	scanf("%d%d",&n,&m);
	top[1]=1,dep[1]=1;
	// for(int i=1;i<=n;++i)num[i]=qr;
	for(int i=1;i<=n;++i)scanf("%d",&num[i]);
	for(int i=1;i<n;++i)
	{
		// int a=qr,b=qr;
		int a,b;
		scanf("%d%d",&a,&b);
		add(a,b);
		add(b,a);
	}
	get_son(1);
	dfs(1);
	// for(int i=1;i<=n;++i)printf("%d ",top[i]);
	// 	putchar('\n');
	char op[50];
	for(int i=1;i<=m;++i)
	{
		cin>>op+1;
		if(op[1]=='Q')
		{
			// int a=qr,b=qr;
			int a,b;
			scanf("%d%d",&a,&b);
			printf("%d\n",ask(a,b));
		}else
		{
			int a,b,pos;
			scanf("%d%d%d",&a,&b,&pos);
			re(a,b,pos);
		}
	}
}
int main()
{
	#ifndef ONLINE_JUDGE
	freopen("in.in","r",stdin);
	freopen("out.out","w",stdout);
	#endif
	init();
	return 0;
}

正片后记:
思路清晰地打完代码,然后顺利地爆了零。
改了一天多,最后无处可改了,想着就把快读注释了,再试试。
然后就A了。
所以就有了本篇题解的挠餐题目。
在我得到一个完美的板子前我是不会改标题的尽管这看起来很唐
所以。

急急急,求完全正确的快读板子!!!

标签:rt,now,急急,top,define,板子,int,完全正确,rk
From: https://www.cnblogs.com/shining-like-stars/p/18204773

相关文章

  • 面试板子
    插入排序for(inti=1;i<=n;i++)for(intj=i;j>=2;j--){if(a[j]>a[j-1])swap(a[j],a[j-1]);elsebreak;} 选择排序for(inti=1;i<=n;i++)for(intj=i+1;......
  • 莫队(板子)
    莫队参考博客玄学暴力区间操作算法PPT解释的很清楚啦~,导致我没什么可写的\(qwq\)把所有询问离线下来后排序(左端点按块,右端点升序),然后从一个小区间通过左右端点的移动扩大区间,更新答案。复杂度主要在区间扩展,也就是左右指针的移动,对于莫队所有的优化几乎都是调整分块或排......
  • 下面哪种异步处理的方法完全正确 ()。
    选项:A、在对数据总线进行异步处理前转化成GrayCode,然后打拍处理,同步后再转换成原码B、在模块A,有两个控制信号通过正确的同步方法把两个信号进行同步到B时钟域,但是在B时钟域,对这两个同步过来的信号进行了逻辑运算,得到另外一个信号C、实现异步FIFO时,在地址穿越时钟域前转化成Gra......
  • 多项式板子
    本页面由洛谷云剪贴板进化而来。免责:多项式可能未经良好测试,并不完善或可能执行时出现问题,如有问题请在本页评论区说明。改自Submission。备份。feature:指令集优化ntt(来自fjzzq2002);转置原理多点求值与插值;2log多项式复合(逆)(改自hly1204github版);开罐即食版多叉半在线卷积......
  • Censoring S(板子)
    题目描述原题来自:USACO2015Feb.Silver给出两个字符串和,每次从前往后找到的一个子串并将其删除,空缺位依次向前补齐,重复上述操作多次,直到串中不含串。输出最终的串。输入格式第一行包含一个字符串,第二行包含一个字符串。样例输入whatthemomooofun......
  • 【计算几何】二维基础 (丑陋的)板子
    符号判断与大小比较intsgn(intx){ if(fabs(x)<eps)return0; elseif(x>=eps)return1; elsereturn-1;}//实数的向上取整函数int_ceil(constdouble&x){longlongk=ceil(x);while(k<x)k++;while(k>x+1)k--;returnk;}点structPoint......
  • 分块(板子)
    “优雅的暴力”——分块分块是一种暴力的优化,虽然效率比线段树、树状数组等数据结构低的多\((N+Q)\sqrt{N}\),但是更加灵活。分块的思想是把整个区间分成几个部分,对于要处理的区间包括两个部分“整块”,和区间边缘的“零散块”,“零散块”直接暴力,“整块”进行整体操作即可。......
  • 板子速查
    基础二分答案intfind1(intx){intl=1,r=n;while(l<r){intmid=(l+r)>>1;if(check(mid))l=mid+1;elser=mid;}returnl;}//l:第一个不满足check()性质的数。intfind2(intx){intl=1,r......
  • 分块板子
    预处理voidinit(){clean();scanf("%lld",&n);for(i=1;i<=n;i++)scanf("%lld",&a[i]);sq=sqrt(n);for(i=1;i<=sq;i++){st[i]=n/sq*(i-1)+1;ed[i]=n/sq*i;}ed[sq]=n;for(i=1;i<......
  • 数论板子
    线性筛求素数intprime[MAXN];//保存素数boolis_not_prime[MAXN]={1,1};//0和1都不是素数//筛选n以内的所有素数voidxxs(intn){for(inti=2;i<=n;++i){if(!is_not_prime[i]){//如果i是素数prime[++prime[0]]=i;......