Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include<bits/stdc++.h>
- #define fi first
- #define se second
- #define pb push_back
- #define pf push_front
- #define popb pop_back
- #define popf pop_front
- #define ins insert
- #define pq priority_queue
- #define minele min_element
- #define maxele max_element
- #define lb lower_bound //first pos >= val
- #define ub upper_bound // first pos > val
- #define cnt_bit __builtin_popcount
- #define debug(...) " [" << #__VA_ARGS__ ": " << (__VA_ARGS__) << "] "
- //#pragma GCC optimize("Ofast")
- //#pragma GCC target("avx,avx2,fma")
- using namespace std;
- mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());
- typedef long long ll;
- typedef pair<ll, ll> pll;
- typedef pair<int, int> pii;
- int d4x[4] = {1, 0, -1, 0}; int d4y[4] = {0, 1, 0, -1};
- int d8x[8] = {0, 1, 1, 1, 0, -1, -1, -1};
- int d8y[8] = {1, 1, 0, -1, -1, -1, 0, 1};
- const ll oo = 1e18;
- const ll maxN = 1e6;
- /* Author : Le Ngoc Bao Anh, 10A5, LQD High School for Gifted Student */
- void maximize(int &a, int b) {
- a = max(a, b);
- }
- void minimize(int &a, int b) {
- a = min(a, b);
- }
- const int N = 2000050;
- int ans[N], a[N], pref[N];
- bitset<3335> dp[101][3335];
- pair<int, pii> qu[N * 30];
- bool vs[N][2];
- ll p[N];
- int n;
- void dfs(int pos, int x, int y, int target) {
- if(pos > n) return;
- if(dp[n][target][target]) return;
- if(dp[pos][x][y]) return;
- dp[pos][x][y] = true;
- if(x + a[pos + 1] <= target) dfs(pos + 1, x + a[pos + 1], y, target);
- if(dp[n][target][target]) return;
- if(y + a[pos + 1] <= target) dfs(pos + 1, x, y + a[pos + 1], target);
- if(dp[n][target][target]) return;
- if(pref[pos + 1] - x - y <= target) dfs(pos + 1, x , y, target);
- }
- void backtrack(ll tot, int msk, ll g, int n, int cnt) {
- if(vs[msk][tot == g]) return;
- vs[msk][tot == g] = true;
- if(msk == (1 << n) - 1) {
- if(tot == g) {
- for(int i = 1; i <= n; i++) cout << ans[i] << " ";
- exit(0);
- }
- return;
- }
- if(tot == g) backtrack(0, msk, g, n, cnt + 1);
- for(int i = 1; i <= n; i++) {
- if(msk >> (i - 1) & 1) continue;
- if(tot + a[i] <= g) {
- ans[i] = cnt;
- backtrack(tot + a[i], msk | (1 << (i - 1)), g, n, cnt);
- }
- }
- }
- void solve() {
- int k;
- cin >> n >> k;
- ll S = 0;
- bool ok = true;
- for(int i = 1; i <= n; i++) {
- cin >> a[i];
- S = S + a[i];
- ok &= (a[i] == i);
- }
- if(S % k != 0) {
- cout << -1;
- return;
- }
- auto sub1 = [&]() -> void {
- ll g = S / k;
- vector<int> f;
- vector<bool> d((1 << n) + 10, false);
- vector<int> prv((1 << n) + 10, 0);
- for(int msk = 0; msk < (1 << n); msk++) {
- ll tot = 0;
- for(int i = 0; i < n; i++) {
- if(msk >> i & 1) {
- tot += a[i + 1];
- }
- }
- if(tot == g) f.pb(msk);
- }
- d[0] = true;
- for(int msk = 0; msk < (1 << n); msk++) {
- for(auto u : f) {
- if((u & msk) != u) continue;
- if(d[msk ^ u]) {
- d[msk] = true;
- prv[msk] = (u ^ msk);
- break;
- }
- }
- }
- if(!d[(1 << n) - 1]) {
- cout << -1;
- return;
- }
- int msk = (1 << n) - 1;
- int cnt = 0;
- while(msk) {
- cnt++;
- int prev = prv[msk];
- for(int i = 0; i < n; i++) {
- if((msk >> i & 1) && !(prev >> i & 1)) {
- ans[i + 1] = cnt;
- }
- }
- msk = prev;
- }
- for(int i = 1; i <= n; i++) cout << ans[i] << " ";
- };
- if(n <= 10) {
- sub1();
- return;
- }
- auto sub2 = [&]() -> void {
- backtrack(0, 0, S / k, n, 1);
- cout << -1;
- return;
- };
- if(n <= 20) {
- sub2();
- return;
- }
- auto sub3 = [&]() -> void {
- for(int i = 1; i <= n; i++) pref[i] = pref[i - 1] + a[i];
- int g = S / 3;
- dfs(0, 0, 0, g);
- // dp[0][0][0] = true;
- // int x = 0;
- // for(int i = 1; i <= n; i++) {
- // x = x + a[i];
- // int d = min(x, (int)S / 3);
- // for(int j = d; j >= 0; j--) {
- // int y = x - j;
- // y = min(y, (int)S / 3);
- // for(int k = y; k >= 0; k--) {
- // if(dp[i - 1][j][k]) {
- // dp[i][j][k] = true;
- // }
- // if(j >= a[i] && dp[i - 1][j - a[i]][k]) {
- // dp[i][j][k] = true;
- // }
- // if(k >= a[i] && dp[i - 1][j][k - a[i]]) {
- // dp[i][j][k] = true;
- // }
- // }
- // }
- // }
- if(!dp[n][S / 3][S / 3]) {
- cout << -1;
- return;
- }
- int x = S / 3, y = S / 3, pos = n;
- while(pos) {
- int turn = 0;
- if(x >= a[pos] && dp[pos - 1][x - a[pos]][y]) turn = 1;
- else if(y >= a[pos] && dp[pos - 1][x][y - a[pos]]) turn = 2;
- else turn = 3;
- ans[pos] = turn;
- if(turn == 1) x -= a[pos];
- if(turn == 2) y -= a[pos];
- pos--;
- }
- for(int i = 1; i <= n; i++) cout << ans[i] << " ";
- };
- if(k == 3 && n <= 100) {
- sub3();
- return;
- }
- auto sub4 = [&]() -> void {
- if(n % 6 == 0) {
- int mid = (n / 2);
- int turn = 1;
- for(int i = 1; i <= mid; i++) {
- ans[i] = ans[n - i + 1] = turn;
- turn++; if(turn > 3) turn = 1;
- }
- for(int i = 1; i <= n; i++) cout << ans[i] << " ";
- return;
- }
- if(n % 3 == 0) {
- int mid = (n - 3) / 2;
- int turn = 1;
- for(int i = 1; i <= mid; i++) {
- ans[i] = ans[n - 3 - i + 1] = turn;
- turn++; if(turn > 3) turn = 1;
- }
- swap(ans[n - 3], ans[n - 4]);
- ans[n - 2] = 2;
- ans[n - 1] = 3;
- ans[n] = 1;
- for(int i = 1; i <= n; i++) cout << ans[i] << " ";
- ll tot[4] = {0};
- for(int i = 1; i <= n; i++) {
- tot[ans[i]] += i;
- }
- return;
- }
- };
- auto sub5 = [&]() -> void {
- for(int i = 1; i <= k; i++) {
- ll target = S / k;
- for(int j = n; j >= 1; j--) {
- if(target >= a[j] && !ans[j]) {
- ans[j] = i;
- target -= a[j];
- }
- }
- }
- for(int i = 1; i <= n; i++) {
- if(!ans[i]) {
- cout << -1;
- return;
- }
- }
- for(int i = 1; i <= n; i++) cout << ans[i] << " ";
- };
- if(k == 3 && (n % 3 == 0) && ok) {
- sub4();
- return;
- }
- sub5();
- }
- int main()
- {
- ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0);
- #ifndef ONLINE_JUDGE
- freopen("input.txt", "r", stdin);
- freopen("output.txt", "w", stdout);
- #else
- //online
- #endif
- int tc = 1, ddd = 0;
- // cin >> tc;
- while(tc--) {
- //ddd++;
- //cout << "Case #" << ddd << ": ";
- solve();
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement