• CF516D Drazil and Morning Exercise 题解


    安利(:) 杂题选做

    题目链接-Codeforces


    不难发现权值分布组成了一棵以(f_x)最小的(x)为根的树(,)其中父亲的权值一定(leq)儿子的权值(.)

    那么直接(two-pointers,)然后用并查集维护当前的答案就可以做到 (O(nα(n)))处理一组询问 (.)

    (two-pointers)的细节大概是(,)考虑(l,r)的移动(,) 不难发现(r)变小是不会影响联通情况的(,)所以就从大往小扫(.)

    复杂度 (O(qnα(n)).)

    代码 (:)

    #include <bits/stdc++.h>
    #define LL long long
    using namespace std;
    template <typename T> void read(T &x){
    	x = 0; int f = 1; char ch = getchar();
    	while (!isdigit(ch)) {if (ch == '-') f = -1; ch = getchar();}
    	while (isdigit(ch)) {x = x * 10 + ch - '0'; ch = getchar();}
    	x *= f;
    }
    inline void write(int x){if (x > 9) write(x/10); putchar(x%10+'0'); }
    
    const int N = 100050;
    int To[N<<1],Ne[N<<1],Dis[N<<1],He[N],_;
    inline void add(int x,int y,int w){
    	++_; To[_] = y,Ne[_] = He[x],Dis[_] = w,He[x] = _;
    	++_; To[_] = x,Ne[_] = He[y],Dis[_] = w,He[y] = _;
    }
    int n; LL a[N]; int p[N],fa[N],dpt[N]; vector<int>ch[N];
    inline bool cmp(int x,int y){ return (a[x] != a[y]) ? (a[x] > a[y]) : (dpt[x] > dpt[y]); }
    
    struct DS{
    	int cnt[N],ans,fa[N],size[N];
    	inline void init(){ memset(cnt,0,(n+1)<<2),ans = 0; for (int i = 1; i <= n; ++i) fa[i] = i,size[i] = 1,++cnt[1]; }
    	inline int Find(int x){ return x == fa[x] ? x : (fa[x] = Find(fa[x])); }
    	inline void Merge(int x,int y){
    		x = Find(x),y = Find(y); if (x == y) return;
    		if (size[x] > size[y]) swap(x,y);
    		--cnt[size[x]],--cnt[size[y]]; size[y] += size[x]; ++cnt[size[y]];
    		ans = max(ans,size[y]);
    		fa[x] = y;
    	}
    	inline void Dec(int x){
    		x = Find(x); --cnt[size[x]];
    		if (size[x] == ans && !cnt[size[x]]) --ans;
    		--size[x]; ++cnt[size[x]];
    	}
    	inline int Ans(){ return ans; }
    }T;
    
    namespace subtask1{
    	LL dis[N];
    	inline void dfs(int x,int f){ if (f == -1) dis[x] = 0; for (int y,p = He[x]; p ; p = Ne[p]) if ((y=To[p])^f) dis[y] = dis[x] + Dis[p],dfs(y,x); }
    	inline void solve(){
    		int i,mx,x,y;
    		dfs(1,-1); for (mx = 1,i = 2; i <= n; ++i) if (dis[i] > dis[mx]) mx = i;
    		x = mx,dfs(x,-1); for (mx = 1,i = 2; i <= n; ++i) if (dis[i] > dis[mx]) mx = i; y = mx;
    		for (i = 1; i <= n; ++i) a[i] = dis[i];
    		dfs(y,-1); for (i = 1; i <= n; ++i) a[i] = max(a[i],dis[i]);
    	}
    }
    
    inline void dfs(int x){
    	dpt[x] = dpt[fa[x]]+1;
    	for (int y,p = He[x]; p ; p = Ne[p]) if ((y=To[p])^fa[x]) fa[y] = x,dfs(y),ch[x].push_back(y);
    }
    
    inline int solve(LL d){
    	int ans = 1,l,r,x,i;
    	T.init();
    	for (l = r = 1; l <= n; ++l){
    		while (r < n && a[p[l]]-a[p[r+1]] <= d){
    			++r; x = p[r];
    			for (i = 0; i < ch[x].size(); ++i) T.Merge(x,ch[x][i]);
    		}
    		ans = max(ans,T.Ans());
    		T.Dec(p[l]);
    	}
    	return ans;
    }
    
    int main(){
    	int i,x,y,z,Rt;
    	read(n);
    	for (i = 1; i < n; ++i) read(x),read(y),read(z),add(x,y,z);
    	subtask1::solve();
    	for (Rt = 1,i = 2; i <= n; ++i) if (a[i] < a[Rt]) Rt = i;
    	dfs(Rt);
    	for (i = 1; i <= n; ++i) p[i] = i;
    	sort(p+1,p+n+1,cmp);
    	int q; LL v;
    	read(q); while (q--) read(v),write(solve(v)),putchar('
    ');
    	return 0;
    }
    
  • 相关阅读:
    Django(模板语言-自定义filter和simple_tag)
    vue项目创建步骤小结
    scrapy 相关
    face parsing(人脸解析)
    FSRNet: End-to-End Learning Face Super-Resolution with Facial Priors论文阅读
    第一周,深度学习的实用层面
    如何阅读英文文献
    学习笔记
    Joint Super-Resolution and Alignment of Tiny Faces
    Super-FAN:Integrated facial landmark localization and super-resolution of real-world low resolution faces in arbitrary poses with GANs论文阅读
  • 原文地址:https://www.cnblogs.com/s-r-f/p/13581367.html
Copyright © 2020-2023  润新知