zoukankan      html  css  js  c++  java
  • P3261 [JLOI2015]城池攻占 [贪心,左偏树]

    板子吧,左偏树合并是 1log 的,按照深度合并,而且可以打 tag,pushdown。

    // by Isaunoya
    #include<bits/stdc++.h>
    #define int long long
    using namespace std;
    struct io {
    	char buf[1 << 27 | 3], *s;
    	int f;
    	io() { f = 0, buf[fread(s = buf, 1, 1 << 27, stdin)] = '
    '; }
    	io& operator >> (int&x) {
    		for(x = f = 0; !isdigit(*s); ++s) f |= *s  == '-';
    		while(isdigit(*s)) x = x * 10 + (*s++ ^ 48);
    		return x = f ? -x : x, *this;
    	}
    };
    
    int n, m;
    const int maxn = 3e5 + 53;
    vector <int> g[maxn];
    int qwq[maxn], val[maxn], mul[maxn], add[maxn];
    int h[maxn];
    int v[maxn], c[maxn];
    
    int rt[maxn], ls[maxn], rs[maxn];
    
    void down(int p, int c, int vv) {
    	if(! p) return;
    	v[p] *= c, v[p] += vv;
    	mul[p] *= c, add[p] *= c; add[p] += vv;
    }
    
    void down(int p) {
    	down(ls[p], mul[p], add[p]);
    	down(rs[p], mul[p], add[p]);
    	mul[p] = 1, add[p] = 0;
    }
    
    int dis[maxn];
    int merge(int x, int y) {
    	if(!x || !y) return x + y;
    	down(x), down(y);
    	if(v[x] > v[y]) swap(x, y);
    	rs[x] = merge(rs[x], y);
    	if(dis[ls[x]] < dis[rs[x]]) swap(ls[x], rs[x]);
    	dis[x] = dis[rs[x]] + 1;
    	return x;
    }
    
    int ans1[maxn], ans2[maxn];
    
    int dep[maxn];
    void dfs(int u, int f) {
    	dep[u] = dep[f] + 1;
    	for(int v: g[u]) dfs(v, u), rt[u] = merge(rt[u], rt[v]);
    	while(rt[u] && v[rt[u]] < h[u]) {
    		down(rt[u]); ++ ans1[u];
    		ans2[rt[u]] = dep[c[rt[u]]] - dep[u];
    		rt[u] = merge(ls[rt[u]], rs[rt[u]]);
    	}
    	if(qwq[u]) down(rt[u], val[u], 0);
    	else down(rt[u], 1, val[u]);
    }
    
    signed main() {
    #ifdef LOCAL
    	freopen("testdata.in", "r", stdin);
    #endif
    	io in;
    	in >> n >> m;
    	for(int i = 1 ; i <= n ; i ++) in >> h[i];
    	for(int i = 2 ; i <= n ; i ++) {
    		int f;
    		in >> f >> qwq[i] >> val[i];
    		g[f].push_back(i);
    	}
    	for(int i = 1 ; i <= m ; i ++) {
    		in >> v[i] >> c[i];
    		mul[i] = 1;
    		rt[c[i]] = merge(rt[c[i]], i);
    	}
    	dfs(1, 0);
    	while(rt[1]) {
    		down(rt[1]);
    		ans2[rt[1]] = dep[c[rt[1]]];
    		rt[1] = merge(ls[rt[1]], rs[rt[1]]);
    	}
    	for(int i = 1 ; i <= n ; i ++)
    		cout << ans1[i] << '
    ';
    	for(int i = 1 ; i <= m ; i ++) 
    		cout << ans2[i] << '
    ';
    	return 0;
    }
    
  • 相关阅读:
    用纯 javascript 提高博客访问量
    大龄程序员交流
    Git 本地仓库操作基本命令
    SoapUI登录测试(2)-- 断言
    SoapUI测试登录
    deleteMany is not a function
    jQuery contextMenu使用
    安装MongoDB -- Windows平台
    TortoiseGit 图标不显示
    C#的自定义滚动条
  • 原文地址:https://www.cnblogs.com/Isaunoya/p/12818874.html
Copyright © 2011-2022 走看看