2019-11-6 CSP-S模拟测

今天的题,除了T2感觉都不是我可做的啊,这真“CSP”呢
(算了算了等我以后变强了再来做吧,先丢在这)
u p d a t e update↓
还是决定补补骗分法:
T1:直接杨辉三角预处理出组合数,然后计算即可。注意:杨辉三角和实际组合数并不是一一对应,而是正好横纵坐标相反,且注意 C [ B + 1 ] [ G C D + 1 ] C[B+1][GCD+1] 要+1,即整体下移左移一位
T2:(一开始读错题了)对于每一个 2 i 1 2i-1 2 i 2i 连弦的,直接找到询问区间里较小的那个数然后 / 2 /2 即可
T3:打表,注意旋转同构,但轴对称是两种不同方案即可

T1

在这里插入图片描述

sol:

在这里插入图片描述

T2

在这里插入图片描述

sol:

在这里插入图片描述
思路:
1. 开一个栈来记录当前的节点,如果放进栈中的是一个右节点,那么就一直弹栈直到弹到合法的左节点为止,每次弹栈处理当前区间的 l , r l,r ,相当于合并当前合法块为一个区间(此时是最小的合法区间),方便以后对每个合法区间建一棵树
2. 如果当前区间的右端点就是当前区间,说明它已经在上一步被处理成了一个合法区间,于是将这个点的父亲标记为前面那个区间的左端点的前一位(相当于合并现在这两个区间,两个合法区间的交集一定是合法的),记录一下节点那条边相连的点
3. 如果当前区间还没有被建树并且当前区间是一个合法区间,对这个区间建树
4. 处理询问,对于每一组询问,判断是否合法,输出它们 L C A LCA 的深度 1 -1 即可

#include <bits/stdc++.h>
using namespace std;
const int N=(int)2e6+5;
int n,m;
int l[N],r[N],f[N][20],dep[N],sta[N],top,fa[N],rt[N],r1,r2,p[N];
vector<int> v[N];
inline int read(){
	int cnt=0,f=1;char c=getchar();
	while(!isdigit(c)){if(c=='-')f=-f;c=getchar();}
	while(isdigit(c)){cnt=(cnt<<3)+(cnt<<1)+(c&15);c=getchar();}
	return cnt*f;
}
void dfs(int u,int RT){
	rt[u]=RT;
	for(int i=1;i<=18;i++)f[u][i]=f[f[u][i-1]][i-1];
	for(int i=0;i<v[u].size();i++){int to=v[u][i];dep[to]=dep[u]+1;f[to][0]=u;dfs(to,RT);}
}
int lca(int x,int y){
	if(dep[x]<dep[y])	swap(x,y);
	for(int i=18;i>=0;i--)
		if(dep[f[x][i]]>=dep[y])	x=f[x][i];
	if(x==y)	return x;
	for(int i=18;i>=0;i--)
		if(f[x][i]^f[y][i])	x=f[x][i],y=f[y][i];
	return f[x][0];
}
int main(){
	n=read(),m=read();
	for(int i=1;i<=(n<<1);i++)p[i]=read();
	for(int i=1;i<=(n<<1);i++){
		l[i]=min(i,p[i]);r[i]=max(i,p[i]);
		while(top&&l[i]<=sta[top]){
			int x=sta[top--];
			l[i]=min(l[i],l[x]);r[i]=max(r[i],r[x]);
		}sta[++top]=i;
	}
	memset(fa,-1,sizeof(fa));memset(rt,-1,sizeof(rt));
	for(int i=1;i<=(n<<1);i++){if(r[i]==i){fa[i]=l[i]-1;v[fa[i]].push_back(i);}}
	for(int i=0;i<=(n<<1);i++){if((!(~rt[i]))&&(v[i].size())){dep[i]=1;dfs(i,i);}}
	for(int i=1;i<=m;i++){
		r1=read(),r2=read();
		if(r1>r2)swap(r1,r2);
		if(!r1){puts("0");continue;}
		if(!(~rt[r1])||!(~rt[r2])){puts("0");continue;}
		if(rt[r1]^rt[r2]){puts("0");continue;}
		cout<<dep[lca(r1,r2)]-1<<'\n';
	}
	return 0;
}

T3

在这里插入图片描述

sol:

在这里插入图片描述

发布了37 篇原创文章 · 获赞 11 · 访问量 1933

猜你喜欢

转载自blog.csdn.net/weixin_42750325/article/details/102943001
今日推荐