• Codeforces Round #480 (Div. 2)题解


    C - Posterized

    混沌的贪心。

    从左往右遍历一遍,对于位置i,如果a[i]的分组被确定了,那么我们直接输出它所在的分组,否则我们从a[i]开始,递减往下找,设找到的第一个元素为x,如果x所在的Group能容得下a[i],那就容纳下a[i],将[x+1,a[i]]都和y分到一组。否则将[x+1,a[i]]分成一组。

    #include <iostream>
    #include <cstring>
    using namespace std;
    const int N = 200000+10;
    
    int n,k,a[N];
    int group[N], size[N];
    int main() {
        scanf("%d%d",&n,&k);
        memset(group,-1,sizeof(group));
        for(int i=1;i<=n;i++) {
            scanf("%d",&a[i]);
            if (group[a[i]] != -1) {
                printf("%d ", group[a[i]]);
                continue;
            }
    
            int x=a[i];
            while(x>=0 && a[i]-x+1<=k && group[x]==-1) x--;
            // not exist
            if(x < 0 || group[x] == -1) {
                x ++;
                for(int j=x;j<=a[i];j++) 
                    group[j] = x, size[x] ++;
                printf("%d ", x);
                continue;
            }
    
            int cnt=a[i]-x;
            if(size[group[x]]+cnt<=k) { // can join
                for(int j=x+1;j<=a[i];j++)
                    group[j]=group[x], size[group[x]]++;
                printf("%d ", group[x]);
            } else {                    // can not join
                for(int j=x+1;j<=a[i];j++)
                    group[j]=x+1, size[x+1] ++;
                printf("%d ", x+1);
            }
        }
    }
    

    D - Perfect Groups

    对每个数字进行分解质因数,指数为偶数的质因子扔掉,指数为奇数的质因子应该保留。如果两个数字保留下的数字的集合相等,那么乘起来就会得到一个完全平方数。集合相等的判定,根据唯一因子分解定理,只需集合内元素乘起来相等。【显然,喵!】

    注意几点:

    • 离散化的预处理
    • 0的处理【FST的喜悦】

    E - The Number Games

    以n为根进行DFS,预处理每个节点深度。从大到小尝试着保留每一个节点。

    求每个点加入进来的耗费,有两种方法。

    • 倍增,从当前枚举的节点,一直往上面跳,跳到我们保留的的节点就打住。
    • 预处理DFS序,用线段树维护:一个节点,一直往上跳,会遇到的第一个保留节点的深度。

    姿势1

    #include <iostream>
    #include <vector>
    using namespace std;
    const int N = 1000000 + 10;
    vector<int> g[N];
    int dep[N], par[N][22];
    int n, k;
    int mark[N];
    
    void dfs(int u, int p) {
        par[u][0] = p;
        for(int i=1;i<21;i++)
            par[u][i] = par[par[u][i-1]][i-1];
    
        for(int i=0;i<g[u].size();i++) {
            int v = g[u][i];
            if (v == p) continue;
            dep[v] = dep[u] + 1;
            dfs(v, u);
        }
    }
    
    int main() {
        scanf("%d %d",&n,&k);
        for(int i=1;i<n;i++) {
            int u,v; scanf("%d%d",&u,&v);
            g[u].push_back(v);
            g[v].push_back(u);
        }
    
        dfs(n, n);
        mark[n] = 1;
        int cnt = 1;
        for (int i = n-1; i >= 1; i --) {
            if (mark[i]) continue;
            int now = i;
            for (int j = 20; j >= 0; j --) {
                if (mark[par[now][j]] == 0)
                    now = par[now][j];
            }
            now = par[now][0];
    
            if (cnt + dep[i] - dep[now] <= n - k) {
                cnt = cnt + dep[i] - dep[now];
                int paiGuLong = i;
                while (paiGuLong != now) {
                    mark[paiGuLong] = 1;
                    paiGuLong = par[paiGuLong][0];
                }
            }
        }
    
        for (int i=1;i<=n;i++)
            if (mark[i]==0)
                printf("%d ", i);
    }
    
    
    
    
  • 相关阅读:
    世界编程大赛第一名编写的程序3D世界
    bool与BOOL
    防浪涌电路
    用户至上,体验第一
    VC菜菜鸟创建多线程任务HelloWorld
    Google,a good dog
    算法学习之路
    巧用VC工程下的rc文件
    堆与栈
    关于信息量的压缩
  • 原文地址:https://www.cnblogs.com/RUSH-D-CAT/p/9017011.html
Copyright © 2020-2023  润新知