zoukankan      html  css  js  c++  java
  • [CF1229C] Konrad and Company Evaluation

    [题目链接]

    https://codeforces.com/contest/1229/problem/C

    [题解]

    维护每个点的可达集合 , 每个点的贡献是 (in_{u} cdot out_{u}) , 在更新时直接维护这个值即可。

    这样为什么复杂度正确呢? 考虑势能分析。

    将每个点的势能定义为其度数。 将度数不超过 (sqrt{N}) 的点集称为 (A) 集 , 其余称为 (B) 集。 显然 (|B| leq sqrt{N})

    如果操作的点在 (A) 集中 , 那么转移的势能不超过 (sqrt{N})

    如果操作的点在 (B) 集中 , 对 (B) 集转移的势能是 (sqrt{N}) ((|B| leq sqrt{N}))。

    而对 (A) 集转移的势能必然和 (A)(B) 的势能同级。 总转移量不超过 (N sqrt{N})

    故时间复杂度 : (O(N sqrt{N}))

    [代码]

    #include <bits/stdc++.h>
    
    using namespace std;
    
    typedef long long LL;
    
    const int MN = 1e6 + 5;
    
    int N , M , deg[MN];
    vector < int > g[MN];
    
    inline LL get(int u) {
    	return (LL) (g[u].size()) * (deg[u] - g[u].size());
    }
    int main() {
    	
    	scanf("%d%d" , &N , &M);
    	for (int i = 0; i < M; ++i) {
    		int v , u; scanf("%d%d" , &v , &u);
    		if (v > u) swap(v , u);
    		g[v].emplace_back(u); ++deg[u]; ++deg[v];
    	}
    	LL ANS = 0;
    	for (int i = 1; i <= N; ++i) ANS += get(i);
    	printf("%lld
    " , ANS);
    	int Q; scanf("%d" , &Q);
    	while (Q--) {
    		int v; scanf("%d" , &v);
    		while (!g[v].empty()) {
    			int u = g[v].back();
    			ANS -= get(u) + get(v);
    			g[v].pop_back(); g[u].emplace_back(v);
    			ANS += get(u) + get(v);
    		}
    		printf("%lld
    " , ANS);
    	}
    	return 0; 
    }
  • 相关阅读:
    Daily Scrum02 12.05
    Daily Scrum02 12.04
    用户调研报告
    Daily Scrum02 12.03
    Daily Scrum02 12.02
    Daily Scrum02 12.01
    Daily Scrum02 11.30
    软件工程项目组Z.XML会议记录 2013/11/27
    Daily Scrum02 11.29
    201509-3 模板生成系统
  • 原文地址:https://www.cnblogs.com/evenbao/p/14029585.html
Copyright © 2011-2022 走看看