Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <iostream>
- #include <iomanip>
- #include <fstream>
- #include <vector>
- #include <numeric>
- #include <algorithm>
- #include <set>
- #include <map>
- #include <cmath>
- #include <stack>
- #include <deque>
- #include <string>
- #include <ctime>
- #include <bitset>
- #include <queue>
- #include <cassert>
- #include<unordered_set>
- #include<unordered_map>
- #include<string.h>
- #include <random>
- #include <chrono>
- #pragma GCC optimize("O3,unroll-loops")
- #pragma GCC target("avx2,bmi,bmi2,lzcnt,popcnt")
- #include <math.h>
- //#include <bit>
- #include <climits>
- using namespace std;
- #define int long long
- #define ll long long
- #define ld double
- #define pi pair<int, int>
- #define pll pair<ll, ll>
- #define vi vector<int>
- #define ull unsigned long long
- #define pb push_back
- #define newl '\n'
- #define all(a) (a).begin(), (a).end()
- #define rall(a) (a).rbegin(), (a).rend()
- #define repeat(a) for (int i31 = 0; i31 < a; ++i31)
- template<typename T>
- istream& operator>>(istream& is, vector<T>& v) {
- for (T& o : v) {
- is >> o;
- }
- return is;
- }
- class Query {
- public:
- int l = 0;
- int r = 0;
- int idx = 0;
- Query(int L, int R, int Num) {
- l = L;
- r = R;
- idx = Num;
- }
- };
- int NOD(int a, int b) {
- if (a < 0 || b < 0) return NOD(abs(a), abs(b));
- return b ? NOD(b, a % b) : a;
- }
- //const ld EPS = 1e-9;
- const ll INF = 1e16 + 3;
- const ll MOD1 = 1000000007;
- const ll POWER = 5;
- const ll HASHMOD1 = 939999971;
- const ll HASHMOD2 = 23;
- const ll MOD2 = 998244353;
- //const ld PHI = atan(1) * 4;
- const ll MOD3 = 1e9 + 7;
- const int root = 31;
- const int root_1 = 128805723;
- const int root_pw = 1 << 23;
- vector<int> dX = { 1, 0, -1, 0, };
- vector<int> dY = { 0, 1, 0, -1 };
- mt19937 MT(chrono::steady_clock::now().time_since_epoch().count());
- ifstream fin("aha.txt");
- const int LOG = 19;
- const int PR = 67;
- const int mM = 305;
- const int block_size = 100;
- const int SSIZE = 1001;
- const int mod = 998244353;
- const ld eps = 1e-8;
- const int iter = 150;
- const int maxN = 10000;
- vector<vector<int>> dp;
- void advance(deque<pi>& dd, int pos, int val) {
- while (!dd.empty() && dd.back().first > val) dd.pop_back();
- dd.push_back({ val, pos });
- }
- void redo(deque<pi>& dd, int l) { // < l -> nahuy
- while (!dd.empty() && dd.front().second < l) dd.pop_front();
- }
- void solve() {
- int N = 0, K = 0, T = 0; cin >> N >> K >> T;
- vector<int> a; a.assign(N, 0);
- for (auto& x : a) cin >> x;
- vector<int> huy;
- vector<int> pizda;
- for (int i = 0; i < N; ++i) {
- if (a[i] >= 0) huy.push_back(a[i]);
- else pizda.push_back(a[i]);
- }
- int N1 = huy.size(); int N2 = pizda.size();
- sort(pizda.begin(), pizda.end());
- reverse(pizda.begin(), pizda.end());
- sort(huy.begin(), huy.end());
- dp.assign(N1 + 1, vector<int>(N2 + 1, INF));
- dp[0][0] = 0;
- vi suf1; vi suf2;
- suf1.assign(N1 + 2, INF); suf2.assign(N2 + 1, INF);
- suf1[0] = suf2[0] = 0;
- vector<int> chosen_mn;
- vector<deque<pi>> hahahahhaa;
- hahahahhaa.assign(N + 1, deque<pi>());
- chosen_mn.assign(2 * N + 1, INF);
- vector<deque<pi>> have_to_do;
- have_to_do.assign(2 * N + 1, deque<pi>());
- have_to_do[0].push_back({ 0, 0 });
- for (int i = 0; i < N1; ++i) {
- int pos_take = T - 2 * abs(huy[i]); pos_take /= K;
- int pr = max(0ll, i + 1 - pos_take); suf1[i + 1] = suf1[pr] + 1;
- dp[i + 1][0] = suf1[i + 1];
- }
- for (int i = 0; i < N2; ++i) {
- int pos_take = T - 2 * abs(pizda[i]); pos_take /= K;
- int pr = max(0ll, i + 1 - pos_take); suf2[i + 1] = suf2[pr] + 1;
- dp[0][i + 1] = suf2[i + 1];
- have_to_do[i + 1].push_back({ dp[0][i + 1], 0 });
- }
- for (int ps1 = 1; ps1 <= N1; ++ps1) {
- have_to_do[ps1].push_back({ dp[ps1][0], ps1});
- for (int ps2 = 1; ps2 <= N2; ++ps2) {
- int fir_poss = (T - 2 * huy[ps1 - 1]); fir_poss /= K;
- dp[ps1][ps2] = min(dp[ps1][ps2], dp[max(0ll, ps1 - fir_poss)][ps2] + 1);
- int sec_poss = (T - 2 * abs(pizda[ps2 - 1])); sec_poss /= K;
- dp[ps1][ps2] = min(dp[ps1][ps2], dp[ps1][max(0ll, ps2 - sec_poss)] + 1);
- int lft = T - 2 * huy[ps1 - 1] + 2 * pizda[ps2 - 1];
- if (lft >= 2 * K) {
- int prs = lft / K;
- if (ps1 + ps2 <= prs) {
- dp[ps1][ps2] = 1;
- }
- else {
- int dval = ps1 + ps2 - prs;
- while (!have_to_do[dval].empty() && have_to_do[dval].front().second <= ps1 - 1) {
- advance(hahahahhaa[dval], have_to_do[dval].front().second, have_to_do[dval].front().first);
- have_to_do[dval].pop_front();
- }
- redo(hahahahhaa[dval], ps1 - prs + 1);
- if (!hahahahhaa[dval].empty()) dp[ps1][ps2] = min(dp[ps1][ps2], hahahahhaa[dval].front().first + 1);
- }
- //dp[ps1][ps2] = min(dp[ps1][ps2], chosen_mn[max(0ll, ps1 + ps2 - prs)] + 1);
- // m : diag_val + prs - m < ps2 -> ps1 + ps2 - prs + prs - m < ps2
- //на диагонали нужен максимум на отрезке [ps1 + 1; ps1 + ps2 - prs - (ps2)] -> [ps1 - prs + 1; ps1 - 1] // [l; r]
- }
- have_to_do[ps1 + ps2].push_back({ dp[ps1][ps2], ps1 });
- chosen_mn[ps1 + ps2] = min(chosen_mn[ps1 + ps2], dp[ps1][ps2]);
- }
- }
- cout << dp[N1][N2] << "\n";
- }
- signed main() {
- ios_base::sync_with_stdio(false);
- cin.tie(0);
- cout.tie(0);
- cout << setprecision(20);
- int T = 1;
- while (T--)
- solve();
- return 0;
- }
- /*
- 6
- 1 2
- 2 3
- 3 4
- 4 5
- 5 6
- 3
- 1 2
- 3 4
- 1 4
- */
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement