1. 程式人生 > >CodeForces 518E Arthur and Questions(貪心 + 思維)題解

CodeForces 518E Arthur and Questions(貪心 + 思維)題解

ios else scanf style cor div rect 數字 \n

題意:給你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\n"); return 0; } pre = tot; } for(int i = 1; i <= n; i++){ if(i != 1) printf(" "); printf("%d", a[i]); } printf("\n"); return 0; }

CodeForces 518E Arthur and Questions(貪心 + 思維)題解