zoukankan      html  css  js  c++  java
  • CF1019G Raining Season【边分治,凸包】

    边分治 + Minkowski 和模板!

    注意特判 (n=1) 的情况。

    #include<bits/stdc++.h>
    #define PB emplace_back
    using namespace std;
    typedef long long LL;
    typedef tuple<int, int, int> tiii;
    const int N = 200003;
    template<typename T>
    void read(T &x){
    	int ch = getchar(); x = 0; bool f = false;
    	for(;ch < '0' || ch > '9';ch = getchar()) f |= ch == '-';
    	for(;ch >= '0' && ch <= '9';ch = getchar()) x = x * 10 + ch - '0';
    	if(f) x = -x;
    }
    template<typename T>
    bool chmin(T &a, const T &b){if(a > b) return a = b, 1; return 0;}
    int n, m, head[N], to[N<<1], nxt[N<<1], va[N<<1], vb[N<<1];
    vector<tiii> E[N];
    void add(int u, int v, int a, int b){
    	static int cnt = 1;
    	to[++cnt] = v; nxt[cnt] = head[u]; head[u] = cnt; va[cnt] = a; vb[cnt] = b;
    	to[++cnt] = u; nxt[cnt] = head[v]; head[v] = cnt; va[cnt] = a; vb[cnt] = b;
    }
    void dfs(int x, int fa){
    	for(int i = 0;i < E[x].size();++ i)
    		if(get<0>(E[x][i]) == fa){
    			E[x].erase(E[x].begin() + i);
    			break;
    		}
    	for(auto _ : E[x]) dfs(get<0>(_), x);
    	while(E[x].size() > 2){
    		tiii s1 = E[x].back(); E[x].pop_back();
    		tiii s2 = E[x].back(); E[x].pop_back();
    		add(++n, get<0>(s1), get<1>(s1), get<2>(s1));
    		add(n, get<0>(s2), get<1>(s2), get<2>(s2));
    		E[x].PB(n, 0, 0);
    	}
    	for(auto _ : E[x]) add(x, get<0>(_), get<1>(_), get<2>(_));
    }
    struct Node {
    	LL x, y;
    	Node(LL _x = 0, LL _y = 0): x(_x), y(_y){}
    	bool operator < (const Node &o) const {return x < o.x || x == o.x && y < o.y;}
    	Node operator + (const Node &o) const {return Node(x + o.x, y + o.y);}
    	Node operator - (const Node &o) const {return Node(x - o.x, y - o.y);}
    	LL operator * (const Node &o) const {return x * o.y - y * o.x;}
    	LL val(LL a){return x * a + y;}
    };
    int siz[N], S, rt, MX;
    bool vis[N<<1];
    void getrt(int x, int fa){
    	siz[x] = 1;
    	for(int i = head[x];i;i = nxt[i])
    		if(to[i] != fa && !vis[i]){
    			getrt(to[i], x);
    			siz[x] += siz[to[i]];
    			if(chmin(MX, abs((siz[to[i]]<<1)-S)))
    				rt = i;
    		}
    }
    void get_hull(vector<Node> &v){
    	if(v.size() < 2) return;
    	vector<Node> hul;
    	sort(v.begin(), v.end());
    	hul.PB(v[0]); hul.PB(v[1]);
    	for(int i = 2;i < v.size();++ i){
    		while(hul.size() > 1 && (hul.back() - hul[hul.size()-2]) * (v[i] - hul.back()) >= 0)
    			hul.pop_back();
    		hul.PB(v[i]);
    	}
    	v = hul;
    }
    vector<Node> all, pa, pb; 
    void calc(vector<Node> &pp, int x, int fa, LL sa, LL sb){
    	pp.PB(sa, sb);
    	for(int i = head[x];i;i = nxt[i])
    		if(to[i] != fa && !vis[i])
    			calc(pp, to[i], x, sa + va[i], sb + vb[i]);
    }
    void solve(int x){
    	MX = 1e9; getrt(x, 0);
    	int a = to[rt], b = to[rt^1];
    	vis[rt] = vis[rt^1] = true;
    	pa.resize(0); pb.resize(0);
    	calc(pa, a, b, va[rt], vb[rt]);
    	calc(pb, b, a, 0, 0);
    	get_hull(pa); get_hull(pb);
    	int ia = 0, ib = 0;
    	while(ia+1 < pa.size() || ib+1 < pb.size()){
    		all.PB(pa[ia] + pb[ib]);
    		if(ia+1 == pa.size() || ib+1 < pb.size() && (pa[ia+1] - pa[ia]) * (pb[ib+1] - pb[ib]) > 0) ++ ib;
    		else ++ ia;
    	}
    	all.PB(pa.back() + pb.back());
    	if(siz[a] > siz[b]) siz[a] = S - siz[b];
    	else siz[b] = S - siz[a];
    	if((S = siz[a]) > 1) solve(a);
    	if((S = siz[b]) > 1) solve(b);
    }
    int main(){
    	read(n); read(m);
    	if(n == 1){for(int i = 0;i < m;++ i) printf("0 "); return 0;} 
    	for(int i = 1, u, v, a, b;i < n;++ i){
    		read(u); read(v); read(a); read(b);
    		E[u].PB(v, a, b); E[v].PB(u, a, b);
    	} dfs(1, 0); S = n; solve(1); get_hull(all);
    	for(int i = 0, j = 0;i < m;++ i){
    		while(j+1 < all.size() && all[j+1].val(i) > all[j].val(i)) ++ j;
    		printf("%lld ", all[j].val(i));
    	}
    }
    
  • 相关阅读:
    Memcached初识
    排序
    查找
    Redis初识

    C#
    C#
    C#
    C#
    C#
  • 原文地址:https://www.cnblogs.com/AThousandMoons/p/14837851.html
Copyright © 2011-2022 走看看