首页 > 其他分享 >CF2013 F2

CF2013 F2

时间:2024-09-22 23:48:49浏览次数:1  
标签:F2 mxx dep back int CF2013 ask mx

CF2013 F2

首先你需要知道 F1 的做法。

我将会给出一个 \(O(n\sqrt n)\) 的,求出整棵树任意节点答案的方法。

对于路径上的点 \(p_1\sim p_m\),终点 \(p_m\),起点 \(p_1\),

设 \(p_i\) 所经不在路径上的最远长度为 \(d_i\)。

那么根据 F1 的结论,我们是通过移动两个指针 \(l,r\),不断判断是否有 \(d_l+l>\max_{k\in [l,r]}(m-k+1+d_k)\),\(d_r+m-r+1\ge \max_{k\in [l,r]}d_k+k\)

在这里我们设 \(a_i=d_i+i,b_i=d_i-i+1\),然后利用 ST 表维护最值进行判断。

事实上我们观察 \(i\) 其实是深度,与此同时如果 \(p_i\to p_{i+1}\) 不是在 \(p_i\) 的树内最长路上的话,\(a_i\) 就是 \(a\) 的一个后缀最大值。反过来 \(b\) 可以从 \(p_m\) 为根的视角来看。

所以我们尝试在 ST 表中维护最值出现的位置,然后维护指针 \(l=1,r=m\),每次看谁移动得更少,就用谁进行判断,如果合法直接 return,否则跳到后继位置(下一个最值位置,注意值相同的跳到最后面去),当然反过来是同理的。

由于我们每一次记录了最值,所以不会影响判断结果的完备性。

而同时我们发现 \(l,r\) 指针所跳都是前/后缀最大值,而这种最大值都是各个长链的链顶提供的,所以总共 \(O(\sqrt n)\) 个,所以我们暴力检验就是正确的。

同时我们可以用尾插ST表,维护递归结构。

#include<bits/stdc++.h>
using namespace std;
#define N 205050
int lg[N],n,m,dep[N],ans[N],mx[N],lst[N];
struct ST{
	int f[N][20],v[N],tag;//尾插ST表hh
	void ins(int x,int k){
		f[x][0]=x,v[x]=k;
		for(int j=1;(1<<j)<=x;++j){
			int lt=x-(1<<j-1);
			f[x][j]=v[f[x][j-1]]>v[f[lt][j-1]]+tag?f[x][j-1]:f[lt][j-1];//维护最前面的/最后面的最值,tag=0说明是取最前的,tag=-1说明是取最后面的
		}
	}
	int ask(int l,int r){
		int k=lg[r-l+1];l+=(1<<k)-1;
		return v[f[r][k]]>v[f[l][k]]+tag?f[r][k]:f[l][k];
	}
}A,B;
vector<int>e[N];
void dfs(int u,int fa){
	lst[u]=fa;dep[u]=dep[fa]+1;
	for(auto v:e[u]){
		if(v==fa)continue;
		dfs(v,u);
		mx[u]=max(mx[u],mx[v]+1);
	}
}
void adt(int dep,int val){
	A.ins(dep,val+dep);
	B.ins(dep,val-dep+1);
}
bool check(int dep){
	if(dep<=1)return 1;
	int mid=dep+1>>1;
	int l=A.ask(1,mid),r=B.ask(mid+1,dep);
	while(1){//长剖,复杂度最多根号!
		if(l-1<=dep-r){
			if(A.v[l]>B.v[B.ask(l+1,dep-l+1)]+dep)return 1;
			if(l>=mid)return 0;
			l=A.ask(l+1,mid);
		}
		else {
			if(B.v[r]+dep>=A.v[A.ask(dep-r+2,r-1)])return 0;
			if(r<=mid+1)return 1;
			r=B.ask(mid+1,r-1);
		}
	}
	return 0;
}
void dfs2(int u,int fa){
	int mxx=0,cmx=0;
	for(auto v:e[u])if(v!=fa){
		if(mx[v]+1>=mxx)cmx=mxx,mxx=mx[v]+1;
		else cmx=max(cmx,mx[v]+1);
	}
	adt(dep[u],mxx);
	ans[u]=check(dep[u]);
	for(auto v:e[u])if(v!=fa){
		adt(dep[u],mx[v]+1==mxx?cmx:mxx);
		dfs2(v,u);
	}
}
void sol(){
	cin>>n;
	for(int i=1,u,v;i<n;++i)cin>>u>>v,e[u].push_back(v),e[v].push_back(u);
	dfs(1,0);
	dfs2(1,0);
	int u,v;cin>>u>>v;
	vector<int>nl,nr;
	while(u!=v){
		if(dep[u]>dep[v])nl.push_back(u),u=lst[u];
		else nr.push_back(v),v=lst[v];
	}
	reverse(nr.begin(),nr.end());
	nl.push_back(u);
	for(auto x:nl)cout<<(ans[x]?"Alice\n":"Bob\n");
	for(auto x:nr)cout<<(ans[x]?"Alice\n":"Bob\n");
	for(int i=1;i<=n;++i)mx[i]=lst[i]=0,e[i].clear();
}
signed main(){
	ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
	B.tag=-1;
	lg[0]=-1;for(int i=1;i<=200000;++i)lg[i]=lg[i>>1]+1;
	int T;cin>>T;
	while(T--){
		sol();
	}
}

标签:F2,mxx,dep,back,int,CF2013,ask,mx
From: https://www.cnblogs.com/spdarkle/p/18426119

相关文章

  • CF2005C Lazy Narek
    记录dp的设计。一开始设计的是f[i][j]表示最后一个选i,匹配到j的最大值,然而这样转移是\(n^2\)的,题目要求\(n*m\).设计成0,1背包,考虑第i个选择或者不选择即可。#include<bits/stdc++.h>usingnamespacestd;constintN=1e3+11;intf[N][6];intlef[N][6],val[N][6],to[N......
  • CF2013E prefix gcd
    给n个数,随意排序,所有前缀的gcd的和的最小值。只想到gcd变化是log次的,所以枚举每个作为开头,然后找让gcd变小的接上。可是这样是\(O(n^2)\).注意,最小的数要放最前面。假设\(x,a_1,a_2....\)和\(a_1,a_2,x...\).(x是最小的)我们有\(x+gcd(a_1,x)\leqa_1\),因为gcd的求法是\(a_......
  • CF2004G 题解
    题意定义关于数字串\(s\)的函数\(f(s)\)表示将\(t\)切分为\(m\)段,要求\(m\)是偶数,假设这些字符串分别为\(t_1,t_2,\ldots,t_m\),有\(s=t_1+t_2+\ldots+t_m\)。定义\(A^x\)表示\(\underbrace{AA\ldotsAA}_{x~\text{times}}\),求一种划分方式,使得\(t_2^......
  • BaseCTF2024 pwn
    [Week1]Ret2textexpfrompwnimport*context(os='linux',arch='amd64',log_level='debug')io=remote("challenge.basectf.fun",32537)#io=process("./Ret2text")ret_addr=0x04011A3payload=(0x20+0......
  • xyctf2024 pwn
    helloworldchecksec大多保护都开启了main函数int__fastcallmain(intargc,constchar**argv,constchar**envp){charbuf[20];//[rsp+0h][rbp-20h]BYREFinit();printf("%s","pleaseinputyourname:");read(0,buf,0x48uLL);p......
  • [WesternCTF2018]shrine
    打开题目就得到了python代码importflaskimportos#导包app=flask.Flask(__name__)#创建一个flask实例,app.config['FLAG']=os.environ.pop('FLAG')#从操作系统的环境变量中读取名为FLAG的值,并将其存储在Flask的配置中,POP:读取后删除该环境变量@app.route('/')#定义一......
  • nRF24L01芯片驱动记录
    nRF24L01芯片驱动记录​ 学习完了usb,了解了部分元器件的功能以及用途后,打算在端午假期用一天的时间完成一个小目标,不过实际上是花了一天半才成功实现,现将驱动nRF24L01芯片的整个过程记录下来。小目标驱动nRF24L01芯片,实现nRF24L01芯片之间的通讯在淘宝问客服找驱动代码​ ......
  • [GXYCTF2019]BabyUpload 1
    打开靶机,上传文件抓包后缀不能带ph,大小写也无法绕过,意味着phtml后缀也无法上传对后缀只过滤ph,我们转变思路上传图片马,用.htaccess使图片马以php格式打开上传图片马上传失败,试一试过滤了哪些字符文件内容过滤了<?我们尝试另一种写法后成功上传<scriptlanguage="php">eval......
  • [ACTF2020 新生赛]Upload
    启动靶机,发现有前端验证先绕过前端验证,在burp中尝试发现验证在文件名后缀,且会重命名文件名发现.ini能上传但是会被重命名,既然不像前端显示只有三种格式能上传,这里我们寻找能绕过的后缀尝试发现phtml能上传成功//PHTML扩展名是PHP的一个模块,它允许在HTML文件中使用PHP......
  • BaseCTF2024-week4&Fin-Crypto部分题目wp
    week4哎呀数据丢失了具体分析我就不说了,最简单的证书分析,base64解码后前三个数据分别就是n,e,d。我当时看得是公主的博客,可以参考:RSA进阶(一)-Kicky_Mu-博客园(cnblogs.com)fromCrypto.Util.numberimport*fromgmpy2import*n=0x00bd278484122aef9a69ec647290219d......