• CodeForces 518E Arthur and Questions(贪心 + 思维)题解


    题意:给你a1~an,k,要求a1 + ... + ak < a2 + .... + ak+1 < a3 + ... + ak+2 <...,然后这里的ai有可能是?,要求你填?的数字,并且使a1~an的绝对值之和最小,不可能输出Incorrect sequence

    思路:由上式要求我们可以得到a1 < ak+1 < ak+k+1 < ....且a2 < ak+2 < ak+k+2 < ....且...,所以可以转化为这样的要求。但是要绝对值最小怎么办,我们每次找连续的一连串?,尽可能让中间的位置为0,这样绝对值最小。所以我们先按中间赋值0这样去操作,然后再根据左右边界对整个区间进行修正,全加或全减一个数使得符合要求。

    代码:

    #include<cmath>
    #include<set>
    #include<queue>
    #include<cstdio>
    #include<vector>
    #include<cstring>
    #include <iostream>
    #include<algorithm>
    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    typedef unsigned long long ull;
    const int maxn = 1e5 + 10;
    const ull seed = 131;
    const int INF = 0x3f3f3f3f;
    const int MOD = 1000000009;
    int n, k, none[maxn];
    ll a[maxn];
    int id(int j, int k, int i){return j * k + i;}
    void solve(int ii, int l, int r){
        int m = (l + r) / 2;
        int num = 0;
        for(int i = m; i <= r; i++)
            a[id(i, k, ii)] = num++;
        num = 0;
        for(int i = m; i >= l; i--)
            a[id(i, k, ii)] = num--;
        int dis;
        if(l != 0){
            dis = a[id(l - 1, k, ii)] - a[id(l, k, ii)];
            if(dis >= 0){
                dis++;
                for(int i = l; i <= r; i++)
                    a[id(i, k, ii)] += dis;
            }
        }
        if(id(r + 1, k, ii) <= n){
            dis = a[id(r, k, ii)] - a[id(r + 1, k, ii)];
            if(dis >= 0){
                dis++;
                for(int i = l; i <= r; i++)
                    a[id(i, k, ii)] -= dis;
            }
        }
    }
    int main(){
        char o[20];
        scanf("%d%d", &n, &k);
        for(int i = 1; i <= n; i++){
            scanf("%s", o);
            if(o[0] == '?'){
                none[i] = 1;
            }
            else{
                sscanf(o, "%lld", &a[i]);
            }
        }
        for(int i = 1; i <= k; i++){
            int l = 0, r = 0, ok = 0;
            for(int j = 0; j * k + i <= n; j++){
                if(none[id(j, k, i)] && (j == 0 || !none[id(j - 1, k, i)])){
                    l = j;
                    ok = 1;
                }
                if(none[id(j, k, i)]){
                    r = j;
                }
                else{
                    if(ok){
                        solve(i, l, r);
                        ok = 0;
                    }
                }
            }
            if(ok) solve(i, l, r);
        }
    
        ll tot = 0, pre;
        for(int i = 1; i <= k; i++){
            tot += a[i];
        }
        pre = tot;
        for(int i = k + 1; i <= n; i++){
            tot = tot - a[i - k] + a[i];
            if(tot <= pre){
                printf("Incorrect sequence
    ");
                return 0;
            }
            pre = tot;
        }
    
        for(int i = 1; i <= n; i++){
            if(i != 1) printf(" ");
            printf("%d", a[i]);
        }
        printf("
    ");
        return 0;
    }
  • 相关阅读:
    vim高亮
    mengning
    4.4内核osal
    tmpvalgrind
    为什么引入协程
    alloc_call_show(转)
    TSAN
    如何查看哪些进程占用Buffer和Cache高(转)
    ASAN详解其他参考链接
    Linux系统与程序监控工具atop教程(转)
  • 原文地址:https://www.cnblogs.com/KirinSB/p/10692913.html
Copyright © 2020-2023  润新知