zoukankan      html  css  js  c++  java
  • 「赛后总结」20200827

    考场上

    先开 T1,emmm,感觉贪心很可做。开 T2,看懂题意 + 手玩样例之后没思路。开 T3,看懂题意 + 手玩样例之后发现暴力修改暴力计算答案有 40pts 还是挺香的,写了个暴力。

    回头看 T1,想起几分钟之前大佬说 9! 暴搜,有点犹豫写贪心还是暴搜,因为不保证自己贪心的正确性打算放最后写。

    看 T2 没思路,会 40pts 的暴力,写了。

    T1 想暴搜,枚举全排列,怎么判断和原序列相比交换了几次?我淦,想不出来。写了个看似正确能过样例的贪心,跑路了。

    预计得分:100 + 40 + 40 = 180

    实际的分:0 + 40 + 40 = 80

    出题人太狠了,把贪心卡的一分没有。。。

    T1

    T2

    T3

    考场上的代码

    #include <cstdio>
    #include <cstring>
    #include <string>
    #include <iostream>
    #include <algorithm>
    #define MAXN 50001
    
    const int mod = 2019;
    int ans, n, m, pthn, head[MAXN], dep[MAXN];
    int fa[MAXN][21], lg[MAXN], size[MAXN];
    struct Edge {
    	int next, to, w;
    }pth[MAXN];
    
    void add(int from, int to, int w) {
    	pth[++pthn].to = to, pth[pthn].next = head[from];
    	pth[pthn].w = w, head[from] = pthn;
    }
    
    void dfs(int u) {
    	dep[u] = dep[fa[u][0]] + 1, size[u] = 1;
    	for (int i = head[u]; i; i =pth[i].next) {
    		int x = pth[i].to;
    		if (x != fa[u][0]) {
    			dfs(x);
    			size[u] += size[x];
    		}
    	}
    }
    
    void dfs1(int u, int k) {
    	for (int i = head[u]; i; i = pth[i].next) {
    		int x = pth[i].to;
    		if (x != fa[u][0]) {
    			dfs1(x, k);
    			ans = (1ll * ans + 1ll * (size[k] - size[x]) * size[x] * pth[i].w % mod) % mod;
    		}
    	}
    }
    
    bool dfs2(int u, int x, int y, int k) {
    	bool flag = false;
    	for (int i = head[u]; i; i = pth[i].next) {
    		int v = pth[i].to;
    		if (dfs2(v, x, y, k)) {
    			pth[i].w = (1ll * pth[i].w + k) % mod;
    			flag = true;
    		}
    	}
    	if (u == x || u == y) return true;
    	return flag;
    }
    
    int lca(int x, int y) {
    	if (dep[x] < dep[y]) std::swap(x, y);
    	while (dep[x] > dep[y]) {
    		x = fa[x][lg[dep[x] - dep[y]] - 1];
    	}
    	if (x == y) return x;
    	for (int k = lg[dep[x]] - 1; k >= 0; --k) {
    		if (fa[x][k] != fa[y][k]) {
    			x = fa[x][k];
    			y = fa[y][k];
    		}
    	}
    	return fa[x][0];
    }
    
    int main() {
    	freopen("network.in", "r", stdin);
    	freopen("network.out", "w", stdout);
    	scanf("%d %d", &n, &m);
    	for (int i = 2, w; i <= n; ++i) {
    		scanf("%d %d", &fa[i][0], &w);
    		add(fa[i][0], i, w);
    	}
    	for (int i = 1; i <= n; ++i) {
    		lg[i] = lg[i - 1] + ((1 << lg[i - 1]) == i);
    	}
    	dfs(1);
    	for (int j = 1; (1 << j) <= n; ++j) {
    		for (int i = 1; i <= n; ++i) {
    			fa[i][j] = fa[fa[i][j - 1]][j - 1];
    		}
    	}
    	std::string opt;
    	for (int i = 1, x, y, k; i <= m; ++i) {
    		std::cin >> opt >> x;
    		if (opt == "INC") {
    			std::cin >> y >> k;
    			int l = lca(x, y);
    			dfs2(l, x, y, k);
    		}
    		else {
    			ans = 0;
    			dfs1(x, x);
    			printf("%d
    ", ans % mod);
    		}
    	}
    	fclose(stdin), fclose(stdout);
    	return 0;
    }
    

    正解

    #include <cstdio>
    #include <cstring>
    #include <string>
    #include <iostream>
    #include <algorithm>
    #define MAXN 50001
    
    void read(int &T) {
    	int x = 0;
    	bool f = 0;
    	char c = getchar();
    	while (c < '0' || c > '9') {
    		if (c == '-') f = !f;
    		c = getchar();
    	}
    	while (c >= '0' && c <= '9') {
    		x = x * 10 + c - '0';
    		c = getchar();
    	}
    	T = f ? -x : x;
    }
    
    void write(int x) {
    	if (x < 0) putchar('-'), write(-x);
    	else {
    		if (x / 10) write(x / 10);
    		putchar(x % 10 + '0');
    	}
    }
    
    const int mod = 2019;
    int n, q, size[MAXN], w[MAXN], pre[MAXN], dfn[MAXN];
    
    namespace Seg {
    	#define lson now << 1
    	#define rson now << 1 | 1
    	struct Node {
    		int l, r, sizz, siz;
    		int sizw, sizzw, lazy;
    	}tree[MAXN << 2];
    	void build(int l, int r, int now) {
    		tree[now].l = l, tree[now].r = r;
    		if (tree[now].l == tree[now].r) {
    			tree[now].siz = size[pre[l]] % mod;
    			tree[now].sizz = size[pre[l]] * size[pre[l]] % mod;
    			tree[now].sizw = size[pre[l]] * w[pre[l]] % mod;
    			tree[now].sizzw = w[pre[l]] * tree[now].sizz % mod;
    			return;
    		}
    		int mid = (tree[now].l + tree[now].r) >> 1;
    		build(l, mid, lson), build(mid + 1, r, rson);
    		tree[now].sizz = (tree[lson].sizz + tree[rson].sizz) % mod;
    		tree[now].siz = (tree[lson].siz + tree[rson].siz) % mod;
    		tree[now].sizw = (tree[lson].sizw + tree[rson].sizw) % mod;
    		tree[now].sizzw = (tree[lson].sizzw + tree[rson].sizzw) % mod;
    	}
    	void pushdown(int now) {
    		if (tree[now].l == tree[now].r) return;
    		tree[lson].lazy = (tree[lson].lazy + tree[now].lazy) % mod;
    		tree[rson].lazy = (tree[rson].lazy + tree[now].lazy) % mod;
    		tree[lson].sizw = (tree[lson].sizw + tree[lson].siz * tree[now].lazy) % mod;
    		tree[lson].sizzw = (tree[lson].sizzw + tree[lson].sizz * tree[now].lazy % mod) % mod;
    		tree[rson].sizw = (tree[rson].sizw + tree[rson].siz * tree[now].lazy) % mod;
    		tree[rson].sizzw = (tree[rson].sizzw + tree[rson].sizz * tree[now].lazy % mod) % mod;
    		tree[now].lazy = 0;
    	}
    	void update(int x, int y, int k, int now) {
    		if (tree[now].l >= x && tree[now].r <= y) {
    			tree[now].lazy = (tree[now].lazy + k) % mod;
    			tree[now].sizw = (tree[now].sizw + tree[now].siz * k % mod) % mod;
    			tree[now].sizzw = (tree[now].sizzw + tree[now].sizz * k % mod) % mod;
    			return;
    		}
    		if (tree[now].lazy != 0) pushdown(now);
    		int mid = (tree[now].l + tree[now].r) >> 1;
    		if (x <= mid) update(x, y, k, lson);
    		if (y > mid) update(x, y, k, rson);
    		tree[now].sizw = (tree[lson].sizw + tree[rson].sizw) % mod;
    		tree[now].sizzw = (tree[lson].sizzw + tree[rson].sizzw) % mod;
    	}
    	int query1(int x, int y, int now) {
    		if (tree[now].l >= x && tree[now].r <= y) {
    			return tree[now].sizw;
    		}
    		if (tree[now].lazy != 0) pushdown(now);
    		int mid = (tree[now].l + tree[now].r) >> 1, ans = 0;
    		if (x <= mid) ans = (ans + query1(x, y, lson)) % mod;
    		if (y > mid) ans = (ans + query1(x ,y, rson)) % mod;
    		return ans;
    	}
    	int query2(int x, int y, int now) {
    		if (tree[now].l >= x && tree[now].r <= y) {
    			return tree[now].sizzw;
    		}
    		if (tree[now].lazy != 0) pushdown(now);
    		int mid = (tree[now].l + tree[now].r) >> 1, ans = 0;
    		if (x <= mid) ans = (ans + query2(x, y, lson)) % mod;
    		if (y > mid) ans = (ans + query2(x ,y, rson)) % mod;
    		return ans;
    	}
    }
    
    namespace Cut {
    	int pthn, head[MAXN], fa[MAXN];
    	int cnt, dep[MAXN], son[MAXN], top[MAXN];
    	struct Edge {
    		int next, to, w;
    	}pth[MAXN];
    	void add(int from, int to, int w) {
    		pth[++pthn].to = to, pth[pthn].next = head[from];
    		pth[pthn].w = w, head[from] = pthn;
    	}
    	void dfs1(int u, int father) {
    		fa[u] = father, dep[u] = dep[father] + 1, size[u] = 1;
    		for (int i = head[u]; i; i = pth[i].next) {
    			int x = pth[i].to;
    			if (x != fa[u]) {
    				w[x] = pth[i].w;
    				dfs1(x, u), size[u] += size[x];
    				if (size[son[u]] < size[x]) son[u] = x;
    			}
    		}
    	}
    	void dfs2(int u, int tp) {
    		top[u] = tp, dfn[u] = ++cnt, pre[cnt] = u;
    		if (son[u]) dfs2(son[u], tp);
    		for (int i = head[u]; i; i = pth[i].next) {
    			int x = pth[i].to;
    			if (x != fa[u] && x != son[u]) dfs2(x, x);
    		}
    	}
    	void change(int x, int y, int k) {
    		while (top[x] != top[y]) {
    			if (dep[top[x]] < dep[top[y]]) std::swap(x, y);
    			Seg::update(dfn[top[x]], dfn[x], k, 1);
    			x = fa[top[x]];
    		}
    		if (dfn[x] > dfn[y]) std::swap(x, y);
    		Seg::update(dfn[x] + 1, dfn[y], k, 1);
    	}
    	int ask(int node) {
    		int ans1 = size[node] * Seg::query1(dfn[node] + 1, dfn[node] + size[node] - 1, 1) % mod;
    		int ans2 = Seg::query2(dfn[node] + 1, dfn[node] + size[node] - 1, 1);
    		return (ans1 - ans2 + mod) % mod;
    	}
    }
    
    int main() {
    	read(n), read(q);
    	for (int i = 2, u, w; i <= n; ++i) {
    		read(u), read(w);
    		Cut::add(u, i, w);
    	}
    	Cut::dfs1(1, 0), Cut::dfs2(1, 1), Seg::build(1, n, 1);
    	std::string opt;
    	for (int i = 1, x, y, k; i <= q; ++i) {
    		std::cin >> opt;
    		read(x);
    		if (opt == "INC") {
    			read(y), read(k);
    			Cut::change(x, y, k);
    		}
    		else {
    			write(Cut::ask(x));
    			puts("");
    		}
    	}
    	return 0;
    }
    
  • 相关阅读:
    oracle 中和mysql的group_concat有同样作用的写法
    sql find_in_set在oracle下的解决方案
    Django项目部署:使用uwsgi和nginx的方式
    virtualenvwrapper.sh报错: There was a problem running the initialization hooks.解决
    html中footer如何一直保持在页底
    mysqldump导出备份数据库报Table ‘performance_schema.session_variables‘ doesn‘t exist
    django-ckeditor添加代码功能(codesnippet)
    Django_外键查询和反查询
    python面向对象编程(OOP)
    Django模型中字段属性choice的使用
  • 原文地址:https://www.cnblogs.com/poi-bolg-poi/p/13573383.html
Copyright © 2011-2022 走看看