1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 #include <bits/stdc++.h> using namespace std;using ll = long long ;int main () { ios::sync_with_stdio (false ); cin.tie (nullptr ); int t; cin >> t; while (t--) { ll n, m, r ,c; cin >> n >> m >> r >> c; ll ans = (n - r) * (2 * m - 1 ); ans += (m - c); cout << ans << "\n" ; } return 0 ; }
依据样例,奇数是 3333333336366,偶数是 3333333366。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 #include <bits/stdc++.h> using namespace std;using ll = long long ;int main () { ios::sync_with_stdio (false ); cin.tie (nullptr ); int t; cin >> t; while (t--) { int n; cin >> n; if (n % 2 == 0 ) { cout << string (n - 2 , '3' ) << "66\n" ; } else if (n < 5 ) { cout << "-1\n" ; } else { cout << string (n - 4 , '3' ) << "6366\n" ; } } return 0 ; }
分奇偶讨论。
对于奇数,最后一次运算是与,会把之前的 1 变成 0,因此答案不会超过n n n ,而且最后一个数取n n n 最优,可以构造2 1 3 4 … n 2\ 1\ 3\ 4\ \dots\ n 2 1 3 4 … n 。
对于偶数,最后一次是或,能增加 1,最优解应当是二进制每一位都是 1,最后三个数取
1 2 3 a[n] = (1 << __lg(n)); a[n - 1 ] = a[n] - 1 ; a[n - 2 ] = a[n] - 2 ;
即可,前面可以随意构造,我的写法是先放所有偶数再放所有奇数,保证末尾是 1。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 #include <bits/stdc++.h> using namespace std;using ll = long long ;int main () { ios::sync_with_stdio (false ); cin.tie (nullptr ); int t; cin >> t; while (t--) { int n; cin >> n; vector<int > a (n + 1 ) ; if (n % 2 == 0 ) { a[n] = (1 << __lg(n)); a[n - 1 ] = a[n] - 1 ; a[n - 2 ] = a[n] - 2 ; int num = 0 ; for (int i = 1 ; i <= n - 3 ; i++) { if (num == a[n] - 3 ) num = a[n] - 1 ; if (num == a[n] - 4 ) num = a[n]; if (num == n) num = -1 ; a[i] = (num += 2 ); } } else { int num = 0 ; for (int i = 1 ; i <= n; i++) { a[i] = ++num; } a[1 ] = 2 , a[2 ] = 1 ; } int ans = 0 ; for (int i = 1 ; i <= n; i++) { i & 1 ? ans &= a[i] : ans |= a[i]; } cout << ans << "\n" ; for (int i = 1 ; i <= n; i++) { cout << a[i] << " \n" [i == n]; } } return 0 ; }
贪心,谁大就乘到谁上面,所以需要维护哪些数是大的。用单调栈动态维护后缀最大值的位置,同时在栈中记录每个数字的原始大小和幂次。
注意两数比较大小时,需要按原始大小比较,而不是取模后。可以先比较2 2 2 的幂次,也可以取 log2
或用 long double
,相比而言前者更加保险。
时间复杂度Θ ( n ) \Theta(n) Θ ( n ) 。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 #include <bits/stdc++.h> using namespace std;using ll = long long ;constexpr int mod = 1e9 + 7 ;int main () { ios::sync_with_stdio (false ); cin.tie (nullptr ); int t; cin >> t; while (t--) { int n; cin >> n; vector<array<int , 3>> stk; int sum = 0 ; while (n--) { int x; cin >> x; int exp = 0 , pow = 1 ; while (x % 2 == 0 ) { x /= 2 ; exp++; pow <<= 1 ; } while (!stk.empty () && (exp > 30 || x * (1ll << exp) > stk.back ()[0 ])) { auto [nx, nexp, npow] = stk.back (); sum = (sum - 1ll * nx * npow + nx) % mod; pow = (1ll * pow * npow) % mod; exp += nexp; stk.pop_back (); } stk.push_back ({ x, exp, pow }); sum = (sum + 1ll * x * pow) % mod; (sum += mod) %= mod; cout << sum << " \n" [!n]; } } return 0 ; }
二分,但是直接二分答案是不行的,答案没有单调性。需要找个有单调性的东西,比如轮次(称1 , 2 , … , n 1,2,\dots,n 1 , 2 , … , n 为一轮)。如果q q q 轮可行,那q + 2 q+2 q + 2 轮一定可行;如果q q q 轮不可行,那q − 2 q-2 q − 2 轮一定不可行。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 #include <iostream> #include <algorithm> #include <vector> using namespace std;using ll = long long ;const ll inf = 0x3f3f3f3f3f3f3f3f ;int main () { ios::sync_with_stdio (false ); cin.tie (nullptr ); int t; cin >> t; while (t--) { int n, s; cin >> n >> s; s--; int r = 0 ; vector<int > w (n) ; for (int i = 0 ; i < n; ++i) { cin >> w[i]; (r += w[i]) %= n; } vector<vector<int >> E (n); for (int i = 1 ; i < n; ++i) { int u, v; cin >> u >> v; u--, v--; E[u].push_back (v); E[v].push_back (u); } ll ans = inf; auto check = [&](int q) { for (int i = 0 ; i < n; ++i) { auto dfs = [&](this auto && dfs, int u, int p) -> ll { ll sum = w[u]; for (auto v : E[u]) { if (v == p) continue ; sum += dfs (v, u); } sum -= q; sum -= (u + n < r + i); sum -= (u < r + i); if (sum < 0 ) sum = -sum % 2 ; return sum; }; if (dfs (s, -1 ) == 0 ) { ans = min (ans, 1ll * q * n + r + i); return true ; } } return false ; }; int lo = 0 , hi = 1e9 ; while (lo < hi) { int mid = lo + hi >> 1 ; if (check (mid * 2 )) hi = mid; else lo = mid + 1 ; } lo = 0 , hi = 1e9 ; while (lo < hi) { int mid = lo + hi >> 1 ; if (check (mid * 2 + 1 )) hi = mid; else lo = mid + 1 ; } cout << (ans == inf ? -1 : ans) << "\n" ; } return 0 ; }