• 和直径相关的性质:CF842E


    https://codeforces.com/contest/842/problem/E

    关键性质:多条直径点的交集必然非空且一定为连续一段

    也就是说:必然可以划分成两个集合,使得两个集合各选一个点上的路径必然为一条直径

    然后对于此题求端点,我们就可以维护两个集合,然后就行了

    至于这题有什么启发,我现在还没想懂

    #include
    using namespace std;
    //#define int long long
    inline int read(){int x=0,f=1;char ch=getchar(); while(ch<'0'||
    ch>'9'){if(ch=='-')f=-1;ch=getchar();}while(ch>='0'&&ch<='9'){
    x=(x<<1)+(x<<3)+(ch^48);ch=getchar();}return x*f;}
    #define Z(x) (x)*(x)
    #define pb push_back
    //mt19937 rand(time(0));
    //mt19937_64 rand(time(0));
    //srand(time(0));
    #define N 300010
    //#define M
    //#define mo
    int n, m, i, j, k, T;
    int u, d1, d2, mxd, dia; 
    int dep[N], f[N][22]; 
    vector<int>v1, v2; 
    
    int lca(int u, int v) {
    	if(u==v) return u; 
    	if(dep[u]<dep[v]) swap(u, v); 
    	for(int k=20; k>=0; --k) 
    		if(dep[f[u][k]]>=dep[v]) u=f[u][k]; 
    //	printf("%d %d %d\n", u, v, f[u][0]); 
    	if(u==v) return u; 
    	for(int k=20; k>=0; --k)
    		if(f[u][k]!=f[v][k]) u=f[u][k], v=f[v][k]; 
    	return f[u][0]; 
    }
    
    int dis(int x, int y) {
    	int z=lca(x, y); 
    //	printf("dis(%d %d)[%d]=%d\n", x, y, z, dep[x]+dep[y]-2*dep[z]); 
    	return dep[x]+dep[y]-2*dep[z]; 
    }
    
    signed main()
    {
    //	freopen("in.txt", "r", stdin);
    //	freopen("out.txt", "w", stdout);
    //	T=read();
    //	while(T--) {
    //
    //	}
    	n=read(); dep[1]=1; 
    	for(i=2; i<=n+1; ++i) {
    		u=read(); f[i][0]=u; dep[i]=dep[u]+1;
    //		printf("f[%lld][0]=%lld\n", i, f[i][0]) ; 
    		for(k=1; k<=20; ++k) f[i][k]=f[f[i][k-1]][k-1]; 
    		if(i==2) {
    			v1.pb(1); v2.pb(2); dia=1; 
    			printf("%lld\n", v1.size()+v2.size()); 
    			continue; 
    		}
    		d1=dis(v1[0], i); d2=dis(v2[0], i); mxd=max(d1, d2); 
    		if(mxd>dia) {
    			if(d1>dia) {
    				for(auto j : v2) if(dis(j, i)==mxd) v1.pb(j); 
    				v2.clear(), v2.pb(i); 
    			}
    			else {
    				for(auto j : v1) if(dis(j, i)==mxd) v2.pb(j); 
    
    				v1.clear(), v1.pb(i); 
    			}
    			dia=mxd; 
    		}
    		else if(mxd==dia) {
    			if(d1==dia) v2.pb(i); 
    			else v1.pb(i); 
    		}
    		printf("%lld\n", v1.size()+v2.size()); 
    //		printf("dia : %lld || ", dia); 
    //		for(auto i : v1) printf("%lld ", i); printf(" | "); 
    //		for(auto i : v2) printf("%lld ", i); printf("\n"); 
    	}
    	return 0;
    }
    
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
  • 相关阅读:
    Apollo之Docker部署
    在线ios免签是干什么的?
    Java练习题——抽象类、方法以及接口
    LeetCode 每日一题——816. 模糊坐标
    《棒球裁判》:走近棒球运动·球赛规则
    Android学习笔记 2.4.1 实例——图片浏览器 && 2.4.2 实例——强大的图片按钮
    入门力扣自学笔记111 C++ (题目编号622)
    聊聊精益需求的产生过程
    记一次 .NET 某外贸ERP 内存暴涨分析
    elementui上传图片,到达最大数量隐藏上传按钮,判断文件格式是不是png jpg,文件最大5m
  • 原文地址:https://blog.csdn.net/zhangtingxiqwq/article/details/133280849