隊友寫的暴搜+剪枝。ios
#include<bits/stdc++.h> #define ll long long #define maxn 2010 #define mod 998244353 using namespace std; struct cv { int mp[6][6]; int mov; friend bool operator<(cv p, cv q) { for (int i = 0; i < 6; i++) { for (int j = 0; j < 6; j++) { if (p.mp[i][j] != q.mp[i][j]) return p.mp[i][j] < q.mp[i][j]; } } return p.mp[0][0] < q.mp[0][0]; } }dd, hf; int to[4][2] = { 0,1,0,-1,1,0,-1,0 }; int main() { for (int i = 0; i < 6; i++) { for (int j = 0; j < 6; j++) { scanf("%d", &dd.mp[i][j]); } } dd.mov = 0; queue<cv>q; q.push(dd); set<cv>st; st.insert(dd); while (!q.empty()) { dd = q.front(); q.pop(); if (dd.mp[2][5] == 1) { int cnt = 1; for (int i = 4; i >= 0; i--) { if (dd.mp[2][i] != 1) break; cnt++; } int ans = (dd.mov + cnt); if (ans > 10) ans = -1; printf("%d\n", ans); return 0; } if (dd.mov == 10) break; for (int i = 0; i < 6; i++) { for (int j = 0; j < 6; j++) { if (dd.mp[i][j] == 0) { for (int k = 0; k < 4; k++) { int x = i + to[k][0], y = j + to[k][1]; if (x < 0 || x >= 6 || y < 0 || y >= 6 || dd.mp[x][y] == 0) { continue; } int xx = x + to[k][0], yy = y + to[k][1]; if (xx < 0 || xx >= 6 || yy < 0 || yy >= 6 || dd.mp[x][y] != dd.mp[xx][yy]) { continue; } while (xx >= 0 && xx < 6 && yy >= 0 && yy < 6 && dd.mp[x][y] == dd.mp[xx][yy]) { xx = xx + to[k][0], yy = yy + to[k][1]; } xx = xx - to[k][0], yy = yy - to[k][1]; hf = dd; hf.mov++; swap(hf.mp[i][j], hf.mp[xx][yy]); if (!st.count(hf)) { st.insert(hf); q.push(hf); } } } } } } printf("-1\n"); return 0; }
題意:給定一個數組 \(a_n\) ,判斷是否全部的三元集 \((i,j,k)\) 均知足 \(\frac{a_i-a_j}{a_k}\) 爲整數。c++
分析:\(n\) 很小,直接暴力。api
#include <bits/stdc++.h> using namespace std; const int maxn = 55; int a[maxn]; int main() { int n; scanf("%d", &n); for (int i = 1; i <= n; i++) scanf("%d", &a[i]); bool flag = true; for (int i = 1; i <= n; i++) for (int j = 1; j <= n; j++) for (int k = 1; k <= n; k++) if (i != j && j != k && i != k && (a[i] - a[j]) % a[k]) flag = false; if (flag) printf("yes\n"); else printf("no\n"); return 0; }
簽到。數組
#include <bits/stdc++.h> #define ll long long using namespace std; void io() { ios::sync_with_stdio(false); cin.tie(nullptr); cout.tie(nullptr); } int main() { io(); string s; bool f = false; for (int i = 1; i <= 3; ++i) { string x; cin >> x; if (x != "bubble" && x != "tapioka") { if (f) s += " "; s += x; f = true; } } if (s == "") s = "nothing"; cout << s; }
隊友秒了。ui
#include <bits/stdc++.h> using namespace std; int a[2005]; int main() { int t; scanf("%d", &t); while (t--) { int k, len; scanf("%d%d", &k, &len); if (len >= 2000) { printf("-1\n"); continue; } a[1] = -1; int cnt = (1999 + k) % 1998; fill(a + 2, a + 2000, (1999 + k) / 1998); a[1999] += cnt; printf("1999\n"); for (int i = 1; i <= 1999; i++) printf("%d ", a[i]); printf("\n"); } return 0; }
題意:對於一個給定的 \(n\) 求出最大的正整數 \(a\) ,知足 \(\frac{1}{n}=\frac{1}{a\oplus b}+\frac{1}{b}\) ,其中 \(b\) 是一個任意的正整數。this
分析:猜結論,由這個基礎的變換 \(\frac{1}{n}=\frac{1}{n}-\frac{1}{n+1}+\frac{1}{n+1}=\frac{1}{n(n+1)}+\frac{1}{n+1}\) 直接猜 \(a=n(n+1)\oplus (n+1)\) 。spa
#include <bits/stdc++.h> #define ll long long using namespace std; void io() { ios::sync_with_stdio(false); cin.tie(nullptr); cout.tie(nullptr); } int main() { io(); int t; cin >> t; while (t--) { ll n; cin >> n; ll ans = (n * (n + 1ll) ^ (n + 1ll)); cout << ans << '\n'; } }
隊友秒了。code
#include <bits/stdc++.h> using namespace std; const int maxn = 505; char s[maxn]; bitset<maxn> p[20]; int main() { int t; scanf("%d", &t); while (t--) { int n, m; scanf("%d%d", &n, &m); for (int i = 1; i <= m; i++) { scanf("%s", s + 1); p[i].reset(); for (int j = 1; j <= n; j++) if (s[j] == '1') p[i].set(j); } int base = (1 << m) - 1, ans = 20; for (int i = 0; i <= base; i++) { bitset<maxn> cnt; int k = 0; for (int j = 0; j < m; j++) if (i & (1 << j)) cnt |= p[j + 1], k++; if ((int)cnt.count() == n) ans = min(ans, k); } if (ans == 20) printf("-1\n"); else printf("%d\n", ans); } return 0; }
隊友秒了。ip
#include<bits/stdc++.h> #define ll long long #define maxn 10010 #define mod 998244353 using namespace std; int main() { int t; scanf("%d", &t); while (t--) { int n; scanf("%d", &n); priority_queue<int, vector<int>, greater<int> >s; for (int i = 0; i < n; i++) { int x; scanf("%d", &x); s.push(x); } int ans = 0; for (int i = 0; i < n - 1; i++) { int x = s.top(); s.pop(); int y = s.top(); s.pop(); ans += x + y; s.push(x + y); } printf("%d\n", ans); } return 0; }
題意:給定平面上 \(n\) 個點,求平面最大四邊形。ci
分析:顯然先把凸包跑出來,最大四邊形的頂點一定在凸包上。可是這題很是坑,數據中有重點,而且若是凸包上只有三個點,那麼會構成凹四邊形。排除這些特判後就是個旋轉卡殼了,像求平面最大三角形那樣旋轉便可,由於四邊形能夠看做是兩個三角形,咱們以四邊形對角線爲這兩個三角形的底邊,就能寫出一個 \(O(n^2)\) 的旋轉卡殼了。
#define _CRT_SECURE_NO_WARNINGS #pragma GCC optimize(3) #pragma GCC optimize("Ofast") #pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native") #pragma comment(linker, "/stack:200000000") #include <bits/stdc++.h> #define ll long long using namespace std; void io() { ios::sync_with_stdio(false); cin.tie(nullptr); cout.tie(nullptr); } int num; struct Point { ll x, y; Point() {} Point(ll xx, ll yy) :x(xx), y(yy) {} Point operator + (const Point& k1) const { return Point(k1.x + x, k1.y + y); } Point operator - (const Point& k1) const { return Point(x - k1.x, y - k1.y); } Point operator * (ll k1) const { return Point(x * k1, y * k1); } Point operator / (ll k1) const { return Point(x / k1, y / k1); } bool operator < (const Point& b) const { return (x < b.x) || (x == b.x && y < b.y); } bool operator ==(const Point& b) const { return (x == b.x) && (y == b.y); } ll abs() { return x * x + y * y; } ll dis(Point k1) { return ((*this) - k1).abs(); } }; ll cross(Point a, Point b) { return a.x * b.y - a.y * b.x; } //叉積 ll dot(Point a, Point b) { return a.x * b.x + a.y * b.y; } //點積 ll area(Point a, Point b, Point c) { return abs(cross(a - b, a - c)); } vector<Point> ConvexHull(vector<Point>A, int flag = 1) { // flag = 0 不嚴格 flag = 1 嚴格 int n = A.size(); vector<Point>ans(n * 2); sort(A.begin(), A.end()); int now = -1; for (int i = 0; i < A.size(); i++) { while (now > 0 && cross(ans[now] - ans[now - 1], A[i] - ans[now - 1]) < flag) now--; ans[++now] = A[i]; } int pre = now; for (int i = n - 2; i >= 0; i--) { while (now > pre&& cross(ans[now] - ans[now - 1], A[i] - ans[now - 1]) < flag) now--; ans[++now] = A[i]; } ans.resize(now); return ans; } inline int nxt(int i) { return i == num - 1 ? 0 : i + 1; } ll Rotating_calipers(int n, vector<Point>& p) { ll ans = 0; for (int i = 0; i < n; i++) { int p1 = nxt(i); int p2 = nxt(nxt(nxt(i))); for (int j = nxt(nxt(i)); nxt(j) != i; j = nxt(j)) { while (nxt(p1) != j && area(p[i], p[nxt(p1)], p[j]) > area(p[i], p[p1], p[j])) p1 = nxt(p1); if (p2 == j) p2 = nxt(p2); while (nxt(p2) != i && area(p[j], p[nxt(p2)], p[i]) > area(p[j], p[p2], p[i])) p2 = nxt(p2); ans = max(ans, area(p[i], p[p1], p[j]) + area(p[j], p[p2], p[i])); } } return ans; } int main() { io(); int t; cin >> t; while (t--) { int n; cin >> n; vector<Point> p(n); for (auto& i : p) cin >> i.x >> i.y; vector<Point> ch = ConvexHull(p, 0); num = ch.size(); ll maxs = 0; if (ch.size() < 3) maxs = 0; else if (ch.size() == 3) { ll s = area(ch[0], ch[1], ch[2]); for (auto i : p) { if (i == ch[0] || i == ch[1] || i == ch[2]) continue; ll mins = min(area(i, ch[1], ch[2]), min(area(ch[0], i, ch[2]), area(ch[0], ch[1], i))); maxs = max(maxs, s - mins); } } else maxs = Rotating_calipers(ch.size(), ch); cout << ((maxs & 1ll) ? to_string(maxs / 2ll) + ".5\n" : to_string(maxs / 2ll) + "\n"); } }
題意:給定正整數 \(N,M,D\) 求 \(C_M^N\ dmod\ {D}\) 。其中 \(x\ dmod\ y\) 指的是去掉 \(x\) 中全部 \(y\) 因子後取餘數,假設 \(x=z\times y^k(y\nmid z)\) ,那麼 \(x\ dmod\ y=z\mod{y}\) 。
分析:根據表述習慣,咱們改寫爲求解 \(C_N^M\ dmod\ {D}\) 。而後記 \(x\ div\ y\) 爲去掉 \(x\) 中全部 \(y\) 因子。則有:
所以若上式分母與 \(D\) 互質,則
其中 \(inv\) 表示模 \(D\) 的逆元,這個問題只須要簡單的分段就能解決了。
若上式分母與 \(D\) 不互質,咱們先將 \(D\) 的質因子分解:\(D=D_1D_2\cdots D_s=p_1^{a_1}p_2^{a_2}\cdots p_s^{a_s}\) ,其中 \(p_i\) 爲質因子。因而能夠推出:
所以咱們能夠獲得 \(K=\underset{i\in[1,s]}{\min{\frac{k_i}{a_i}}}\) ,而後推出:
由上式,咱們對於全部 \(i\in[1,s]\) 都能求出 \(C^M_N\ div\ D\mod{D_i}\) 的值,而後就能經過擴展中國剩餘定理求出 \(C^M_N\ div \ D\mod{D_i}\) 。
那麼最後還剩下一個問題,怎麼求 \(C^M_N\ div\ D\mod{D_i}\) ,該問題等價於求 \(N!\ div\ D\mod{P}\) 。
咱們將 \(N!\) 分紅兩部分考慮:\(N!=\underset{D\mid i}{\prod^N_{i=1}}{i}\times \underset{D\nmid i}{\prod^N_{i=1}}{i}\) ,即把能整除 \(D\) 的 \(i\) 分爲一類,不能整除的分爲一類。
所以:\(N!\ div\ D\mod{P}=\lfloor \frac{N}{D}\rfloor !\times (\underset{D\nmid i}{\prod^P_{i=1}}{i})^{\lfloor \frac{N}{P}\rfloor}\times\underset{D\nmid i}{\prod^{P\%N}_{i=1}}{i}\mod{P}\)
觀察該式不難發現,對於 \((\underset{D\nmid i}{\prod^P_{i=1}}{i})^{\lfloor \frac{N}{P}\rfloor}\times\underset{D\nmid i}{\prod^{P\%N}_{i=1}}{i}\mod{P}\) 這部分的值,咱們只須要 \(O(P)\) 的預處理後就能 \(O(1)\) 查詢,而後 \(N!\) 每次都可以轉化爲 \(\lfloor \frac{N}{D}\rfloor !\) 的子問題。因爲 \(D\leq1.6e7\) ,咱們能夠計算出任意一個 \(1.6e7\) 之內的數字最多含有 \(8\) 個質因子,所以粗略地估計一下,複雜度上限爲 \(O(8(D+\log_{D}{N}))\) ,固然不可能達到這個複雜度。
#define _CRT_SECURE_NO_WARNINGS #pragma GCC optimize(3) #pragma GCC optimize("Ofast") #pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native") #pragma comment(linker, "/stack:200000000") #include <bits/stdc++.h> #define ll long long using namespace std; void io() { ios::sync_with_stdio(false); cin.tie(nullptr); cout.tie(nullptr); } ll M, N, D, ans; namespace Pollard_Rho { map<ll, ll> MP; inline ll gcd(ll a, ll b) { return b == 0 ? a : gcd(b, a % b); } inline ll mulmod(ll x, ll y, const ll z) { return (x * y - (ll)(((long double)x * y + 0.5) / (long double)z) * z + z) % z; } inline ll powmod(ll a, ll b, const ll mo) { ll s = 1; for (; b; b >>= 1, a = mulmod(a, a, mo)) if (b & 1) s = mulmod(s, a, mo); return s; } bool isPrime(ll p) { // Miller-Rabin const int lena = 10, a[lena] = { 2,3,5,7,11,13,17,19,23,29 }; if (p == 2) return true; if (p == 1 || !(p & 1) || (p == 46856248255981ll)) return false; ll D = p - 1; while (!(D & 1)) D >>= 1; for (int i = 0; i < lena && a[i] < p; i++) { ll d = D, t = powmod(a[i], d, p); if (t == 1) continue; for (; d != p - 1 && t != p - 1; d <<= 1) t = mulmod(t, t, p); if (d == p - 1) return false; } return true; } void reportFactor(ll n) { // 獲得一個素因子 MP.count(n); MP[n]++; } ll ran() { return rand(); } // 隨機數 void getFactor(ll n) { // Pollard-Rho if (n == 1) return; if (isPrime(n)) { reportFactor(n); return; } while (true) { ll c = ran() % n, i = 1, x = ran() % n, y = x, k = 2; do { ll d = gcd(n + y - x, n); if (d != 1 && d != n) { getFactor(d); getFactor(n / d); return; } if (++i == k) y = x, k <<= 1; x = (mulmod(x, x, n) + c) % n; } while (y != x); } } } using namespace Pollard_Rho; void exgcd(ll a, ll b, ll& x, ll& y) { if (!b) x = 1, y = 0; else exgcd(b, a % b, y, x), y -= a / b * x; } ll qpow(ll a, ll b, ll mod) { ll ans = 1; while (b) { if (b & 1) ans = (ans * a) % mod; a = (a * a) % mod; b >>= 1; } return ans; } ll calc_divs(ll m, ll mod) { ll ans = 0; for (ll i = mod; ; i *= mod) { ans += m / i; if ((long double)i * mod > m) return ans; } } ll calc_fac(ll p, ll mod, vector<ll>& fac) { if (p == 0) return 1; return calc_fac(p / mod, mod, fac) * qpow(fac[mod - 1], p / mod, mod) % mod * fac[p % mod] % mod; } ll getinv(ll n, ll mod) { ll x, y; exgcd(n, mod, x, y); return (x + mod) % mod; } ll excrt(ll a, ll m, ll b, ll n) { ll x, y; exgcd(m, n, x, y); ll ret = a * (y + m) % m * n + b * (x + n) % n * m; if (ret >= m * n) ret -= m * n; return ret; } int main() { io(); cin >> N >> M >> D; getFactor(D); vector<ll> ki; ll K = 1e18; for (auto it : MP) { ll p = it.first; ki.emplace_back(calc_divs(N, p) - calc_divs(M, p) - calc_divs(N - M, p)); K = min(ki.back() / it.second, K); } int cnt = 0; ll fmod = 1; for (auto it : MP) { ll p = it.first, a = it.second; ll cur = qpow(p, a, (ll)1e18); ll divs = ki[cnt] - K * a; vector<ll> val(cur); vector<ll> fac(cur); for (int i = 1; i < cur; ++i) val[i] = i; for (ll i = p; i * p <= cur; i *= p) for (ll j = i; j < cur; j += i) val[j] /= p; val[0] = fac[0] = 1; for (int i = 1; i < cur; ++i) fac[i] = fac[i - 1] * val[i] % cur; ll res = calc_fac(N, cur, fac) * getinv(calc_fac(M, cur, fac), cur) % cur * getinv(calc_fac(N - M, cur, fac), cur) % cur * getinv(qpow(D / cur, K, cur), cur) % cur; ans = excrt(ans, fmod, res * qpow(p, divs, cur) % cur, cur); fmod *= cur; ++cnt; } cout << ans; }