有个傻逼二分没看出来,刚正面疯狂白给,大锅。
没补的题给出STD,以后再慢慢补。
A:
dp。
1 #include <cstdio> 2 #include <vector> 3 #include <cstring> 4 #include <algorithm> 5 6 using namespace std; 7 8 typedef long long ll; 9 10 typedef pair<int, int> piir; 11 12 const int N = 100 + 5; 13 14 int n, m, ans; 15 16 int dp[2][N][N][N]; 17 vector <piir> lims[N]; 18 19 inline void Mod(int &x) { 20 static int mod = 998244353;//1e9 + 7; 21 if (x >= mod) x -= mod; 22 } 23 24 int main() { 25 int Case, ans, l, r, x; 26 int i, j, k, t, p; 27 for (scanf("%d", &Case); Case --; ) { 28 ans = 0; 29 scanf("%d %d", &n, &m); 30 for (i = 1; i <= n; i ++) 31 lims[i].clear(); 32 for (i = 0; i < m; i ++) { 33 scanf("%d %d %d", &l, &r, &x); 34 lims[r].push_back(piir(l, x)); 35 } 36 dp[0][0][0][0] = 1; 37 for (i = p = 1; i <= n; i ++, p ^= 1) { 38 for (j = 0; j <= i; j ++) 39 for (k = 0; k <= j; k ++) 40 for (t = 0; t <= k; t ++) 41 dp[p][j][k][t] = 0; 42 for (j = 0; j < i; j ++) 43 for (k = 0; k <= j; k ++) 44 for (t = 0; t <= k; t ++) { 45 Mod(dp[p][j][k][t] += dp[p ^ 1][j][k][t]); 46 Mod(dp[p][i - 1][k][t] += dp[p ^ 1][j][k][t]); 47 Mod(dp[p][i - 1][j][t] += dp[p ^ 1][j][k][t]); 48 Mod(dp[p][i - 1][j][k] += dp[p ^ 1][j][k][t]); 49 } 50 for (j = 0; j < i; j ++) 51 for (k = 0; k <= j; k ++) 52 for (t = 0; t <= k; t ++) 53 for (piir tmp : lims[i]) 54 if (1 + (j >= tmp.first) + (k >= tmp.first) + (t >= tmp.first) != tmp.second) 55 dp[p][j][k][t] = 0; 56 } 57 for (i = 0, p = n & 1; i < n; i ++) 58 for (j = 0; j <= i; j ++) 59 for (k = 0; k <= j; k ++) 60 Mod(ans += dp[p][i][j][k]); 61 printf("%d ", ans); 62 } 63 return 0; 64 }
B:
原题是codeforces 1100F。比较暴力的做法是线段树维护线性基,但是时间复杂度会挂掉。
题解给了个技巧:贪心地维护序列的前缀线性基(上三角形态),对于每个线性基,将出现位置靠右的数字尽可能地放在高位,也就是说在插入新数字的时候,要同时记录对应位置上数字的出现位置,并且在找到可以插入的位置的时候,如果新数字比位置上原来的数字更靠右,就将该位置上原来的数字向低位推。在求最大值的时候,从高位向低位遍历,如果该位上的数字出现在询问中区间左端点的右侧且可以使答案变大,就异或到答案里。
对于线性基的每一位,与它异或过的线性基更高位置上的数字肯定都出现在它右侧(否则它就会被插入在那个位置了),因此做法的正确性显然。
1 #include<bits/stdc++.h> 2 using namespace std; 3 const int MAXN = 500000 + 10; 4 int T, n, m, op, l, r, tmp, ans, a[MAXN], f[MAXN][32], pos[MAXN][32]; 5 inline int Read() { 6 int x = 0, f = 1; char ch = getchar(); 7 while (ch < '0' || ch > '9') { 8 if (ch == '-') f = -f; 9 ch = getchar(); 10 } 11 while (ch >= '0' && ch <= '9') x = x * 10 + ch - '0', ch = getchar(); 12 return x * f; 13 } 14 char s[30]; 15 inline void writeln(int x) { 16 if (x < 0) putchar('-'), x = -x; 17 if (!x) putchar('0'); 18 else { 19 int len = 0; 20 while (x) s[++len] = x % 10 + '0', x /= 10; 21 while (len) putchar(s[len--]); 22 } 23 putchar(' '); 24 } 25 inline void Add(int i, int x) { 26 int k = i; 27 for (int j = 30; j >= 0; --j) f[i][j] = f[i - 1][j], pos[i][j] = pos[i - 1][j]; 28 for (int j = 30; j >= 0; --j) if (x >> j) { 29 if (!f[i][j]) { 30 f[i][j] = x; 31 pos[i][j] = k; 32 break; 33 } else { 34 if (k > pos[i][j]) { 35 tmp = k, k = pos[i][j], pos[i][j] = tmp; 36 tmp = x, x = f[i][j], f[i][j] = tmp; 37 } 38 x ^= f[i][j]; 39 } 40 } 41 } 42 int main() { 43 //freopen("test.in","r",stdin); 44 //freopen("test.out","w",stdout); 45 T = Read(); 46 while (T--) { 47 n = Read(), m = Read(); 48 for (int i = 1; i <= n; ++i) a[i] = Read(), Add(i, a[i]); 49 ans = 0; 50 while (m--) { 51 op = Read(); 52 if (op) a[++n] = Read()^ans, Add(n, a[n]); 53 else { 54 l = Read(), r = Read(); 55 l = (l ^ ans) % n + 1, r = (r ^ ans) % n + 1; 56 if (l > r) swap(l, r); 57 ans = 0; 58 for (int j = 30; j >= 0; --j) if ((ans ^ f[r][j]) > ans && pos[r][j] >= l) ans ^= f[r][j]; 59 writeln(ans); 60 } 61 } 62 for (int i = 1; i <= n; ++i) 63 for (int j = 30; j >= 0; --j) f[i][j] = pos[i][j] = 0; 64 } 65 return 0; 66 }
C:
离散化+背包
1 #include <bits/stdc++.h> 2 3 template <class T> 4 bool Reduce(T &a, T const &b) { 5 return a > b ? a = b, 1 : 0; 6 } 7 8 const int XN = 1e4 + 11; 9 const long long INF = 1e18; 10 11 std::vector<long long> Merge(std::vector<long long> const &a, std::vector<long long> const &b) { 12 std::vector<long long> c(a.size() + b.size() - 1, INF); 13 for (size_t i = 0; i < a.size(); ++i) 14 for (size_t j = 0; j < b.size(); ++j) 15 Reduce(c[i + j], a[i] + b[j]); 16 return c; 17 } 18 19 std::vector<long long> Go(std::vector<std::pair<int, int>> const &a, int dest) { 20 std::vector<long long> c(a.size(), INF), t(a.size(), INF); 21 c[0] = dest == -1 ? 0 : abs(dest - a[0].first); 22 t[0] = 0; 23 for (int i = 1; i < (int)a.size(); ++i) { 24 int len = abs(a[i].first - a[i - 1].first); 25 for (int j = 0; j < i; ++j) 26 t[j] += len; 27 for (int j = i; j >= 1; --j) 28 Reduce(t[j], t[j - 1] + a[i].second); 29 for (int j = 0; j <= i; ++j) 30 Reduce(c[j], t[j] + (dest == -1 ? 0 : abs(dest - a[i].first))); 31 } 32 return c; 33 } 34 35 int main() { 36 // freopen("in","r",stdin); 37 std::ios::sync_with_stdio(0); 38 std::cin.tie(0); 39 int T; std::cin >> T; 40 while (T--) { 41 //std::cerr<<T<<':'; 42 int n, m, k; std::cin >> n >> m >> k; 43 static std::tuple<int, int, int> p[XN]; 44 std::vector<int> x{1}; 45 for (int i = 1; i <= k; ++i) { 46 std::cin >> std::get<0>(p[i]) >> std::get<1>(p[i]) >> std::get<2>(p[i]); 47 x.push_back(std::get<0>(p[i])); 48 } 49 std::sort(x.begin(), x.end()); 50 x.erase(std::unique(x.begin(), x.end()), x.end()); 51 static std::vector<std::pair<int, int>> a[XN]; 52 static long long Ans[XN]; 53 for (size_t i = 0; i < x.size(); ++i) 54 a[i].clear(); 55 for (int i = 1; i <= k; ++i) { 56 a[std::lower_bound(x.begin(), x.end(), std::get<0>(p[i])) - x.begin()].push_back({std::get<1>(p[i]), 57 std::get<2>(p[i])}); 58 Ans[i] = INF; 59 } 60 for (size_t i = 0; i < x.size(); ++i) 61 std::sort(a[i].begin(), a[i].end()); 62 static std::vector<long long> f[2]; 63 64 auto t = a[0]; 65 t.insert(t.begin(), {1, 0}); 66 f[0] = Go(t, (m + 1) / 2); 67 auto g = Go(t, -1); 68 for (size_t i = 0; i < t.size(); ++i) 69 Reduce(Ans[i], g[i]); 70 71 for (int i = 1; i < (int)x.size(); ++i) { 72 auto sp = std::lower_bound(a[i].begin(), a[i].end(), std::make_pair((m + 1) / 2, 0)); 73 std::vector<std::pair<int, int>> t0(a[i].begin(), sp), t1(sp, a[i].end()); 74 t0.push_back({(m + 1) / 2, 0}); std::reverse(t0.begin(), t0.end()); 75 t1.insert(t1.begin(), {(m + 1) / 2, 0}); 76 77 auto f0 = Go(t0, (m + 1) / 2), f1 = Go(t1, (m + 1) / 2), g0 = Go(t0, -1), g1 = Go(t1, -1); 78 79 g0 = Merge(f1, g0); g1 = Merge(f0, g1); 80 81 assert(g0.size() == g1.size()); 82 83 std::vector<long long> g(g0.size()); 84 for (size_t i = 0; i < g.size(); ++i) 85 g[i] = std::min(g0[i], g1[i]); 86 g = Merge(f[(i - 1) & 1], g); 87 88 f[i & 1] = Merge(f[(i - 1) & 1], Merge(f0, f1)); 89 for (size_t j = 0; j < g.size(); ++j) { 90 Reduce(Ans[j], g[j] += x[i] - x[i - 1]); 91 f[i & 1][j] += x[i] - x[i - 1]; 92 } 93 } 94 95 for (int i = 1; i <= k; ++i) 96 std::cout << Ans[i] << (i == k ? ' ' : ' '); 97 } 98 return 0; 99 }
D:
一开始就想到了题解里用堆维护撞车事件的做法,想法正确且显然,时间复杂度O(nlogn)。唯一的难点在于非常难写。
直到比赛结束我都没意识到这题可以二分……不应该。
1 /* basic header */ 2 #include <iostream> 3 /* define */ 4 #define ll long long 5 #define dou double 6 #define pb emplace_back 7 #define mp make_pair 8 #define sot(a,b) sort(a+1,a+1+b) 9 #define rep1(i,a,b) for(int i=a;i<=b;++i) 10 #define rep0(i,a,b) for(int i=a;i<b;++i) 11 #define eps 1e-8 12 #define int_inf 0x3f3f3f3f 13 #define ll_inf 0x7f7f7f7f7f7f7f7f 14 #define lson (curpos<<1) 15 #define rson (curpos<<1|1) 16 /* namespace */ 17 using namespace std; 18 /* header end */ 19 20 const int maxn = 2e5 + 10; 21 struct Car { 22 int l, s, v; 23 } car[maxn]; 24 25 int n; 26 27 int check(double x) { 28 double currS = car[n].s - car[n].v * x; // 最前面的车行驶x时间之后离stopline的距离,也可以认为是一个“容忍距离”,决定了容忍多少辆车相撞 29 for (int i = n - 1; i >= 0; i--) { // 遍历前面的每一辆车 30 // 如果 前一辆车行驶x时间之后离stopline的距离 比 最前面的车行驶x时间之后离stopline的距离塞下下一辆车 还短 31 // 那么当前这辆车一定不会和身后的车相撞,那么允许后面的车走过stopline 32 if (car[i].s - car[i].v * x <= currS + car[i + 1].l) currS += car[i + 1].l; 33 else currS = car[i].s - car[i].v * x; // 否则会相撞,答案更新为当前的车在前面无阻碍的情况下行驶x时间离stopline的距离 34 } 35 return currS <= eps; // 如果小于等于0,说明行驶x时间后必然可以到达stopline 36 } 37 38 int main() { 39 while (~scanf("%d", &n)) { 40 rep1(i, 0, n) scanf("%d", &car[i].l); 41 rep1(i, 0, n) scanf("%d", &car[i].s); 42 rep1(i, 0, n) scanf("%d", &car[i].v); 43 double l = 0, r = 1e18; // 二分到达时间 44 while (r - l > eps) { 45 double mid = (l + r) / 2; 46 if (check(mid)) r = mid; 47 else l = mid; 48 } 49 printf("%.6f ", r); 50 } 51 return 0; 52 }
E:
从一开始就很多人过的题,但由于solo训练所以甩锅给队友(
网络流求最小割模板题。
1 #include <bits/stdc++.h> 2 3 template <class T> 4 bool Reduce(T &a, T const &b) { 5 return a > b ? a = b, 1 : 0; 6 } 7 8 const int XN = 1e4 + 11; 9 const int INF = 2e9; 10 const long long oo = 1e18; 11 12 int n; 13 long long sp[XN]; 14 15 namespace D { 16 struct Edge { 17 int to, v; 18 }; 19 20 std::vector<Edge> G[XN]; 21 22 void Run() { 23 static bool ud[XN]; 24 std::priority_queue<std::pair<long long, int>, std::vector<std::pair<long long, int>>, std::greater<std::pair<long long, int>>> Q; 25 std::fill(sp + 1, sp + 1 + n, oo); 26 std::fill(ud + 1, ud + 1 + n, 0); 27 sp[1] = 0; 28 Q.push(std::make_pair(0, 1)); 29 while (!Q.empty()) { 30 int pos = Q.top().second; Q.pop(); 31 if (ud[pos]) 32 continue; 33 ud[pos] = 1; 34 for (auto &e : G[pos]) { 35 int u = e.to; 36 if (Reduce(sp[u], sp[pos] + e.v)) 37 Q.push(std::make_pair(sp[u], u)); 38 } 39 } 40 } 41 } 42 43 namespace I { 44 struct Edge { 45 int to, cap, v; 46 Edge *rev, *pre; 47 } *G[XN], *preArc[XN]; 48 49 void AddEdge(int x, int y, int c) { 50 G[x] = new Edge{y, c, 0, NULL, G[x]}; 51 G[y] = new Edge{x, 0, 0, G[x], G[y]}; 52 G[x]->rev = G[y]; 53 } 54 55 int Aug() { 56 int d = INF; 57 for (int pos = n; preArc[pos]; pos = preArc[pos]->rev->to) 58 Reduce(d, preArc[pos]->cap - preArc[pos]->v); 59 for (int pos = n; preArc[pos]; pos = preArc[pos]->rev->to) { 60 preArc[pos]->v += d; 61 preArc[pos]->rev->v -= d; 62 } 63 return d; 64 } 65 66 long long Run() { 67 static int num[XN], d[XN]; 68 static Edge *cArc[XN]; 69 std::fill(num + 1, num + n, 0); 70 std::fill(d + 1, d + 1 + n, 0); 71 std::copy(G + 1, G + 1 + n, cArc + 1); 72 num[0] = n; preArc[1] = 0; 73 long long flow = 0; 74 for (int pos = 1; d[1] < n;) { 75 if (pos == n) { 76 flow += Aug(); 77 pos = 1; 78 } 79 bool adv = 0; 80 for (Edge *&e = cArc[pos]; e; e = e->pre) { 81 int u = e->to; 82 if (e->cap > e->v && d[u] + 1 == d[pos]) { 83 adv = 1; 84 preArc[pos = u] = e; 85 break; 86 } 87 } 88 if (!adv) { 89 if (--num[d[pos]] == 0) 90 break; 91 d[pos] = n; 92 for (Edge *e = cArc[pos] = G[pos]; e; e = e->pre) 93 if (e->cap > e->v) 94 Reduce(d[pos], d[e->to] + 1); 95 num[d[pos]]++; 96 if (pos != 1) 97 pos = preArc[pos]->rev->to; //cArc 98 } 99 } 100 return flow; 101 } 102 } 103 104 int main() { 105 //freopen("test1.in","r",stdin); 106 std::ios::sync_with_stdio(0); 107 std::cin.tie(0); 108 int T; std::cin >> T; 109 while (T--) { 110 int m; std::cin >> n >> m; 111 for (int i = 1; i <= n; ++i) { 112 D::G[i].clear(); 113 I::G[i] = 0; 114 } 115 for (int i = 1; i <= m; ++i) { 116 int x, y, v; 117 std::cin >> x >> y >> v; 118 D::G[x].push_back({y, v}); 119 } 120 121 D::Run(); 122 123 if (sp[n] == oo) 124 std::cout << 0 << ' '; 125 else { 126 for (int pos = 1; pos <= n; ++pos) 127 for (auto &e : D::G[pos]) 128 if (sp[e.to] - sp[pos] == e.v) 129 I::AddEdge(pos, e.to, e.v); 130 131 std::cout << I::Run() << ' '; 132 } 133 } 134 return 0; 135 }
F:
一开始看错题了,以为是对半取,那就是个傻逼贪心细节题。后来补充了题意之后瞬间难度上升。
#include<bits/stdc++.h> typedef long long ll; using namespace std; const int maxp = 26 + 5; const int maxn = 400000 + 5; struct Suffix_Node { int trans[maxp], par, len; void Clear() { memset(trans, 0, sizeof(trans)); par = len = 0; } }; class Suffix_Automaton { private: Suffix_Node S[maxn]; int p, np, size, crp; public: Suffix_Automaton(): p(1), np(1), size(1), crp(1) {}; const void Clear() { for (int i = 0; i <= size; ++i) S[i].Clear(); p = np = size = crp = 1; } const int Match(const char ch)const { return S[crp].trans[ch - 'a']; } const void Withdraw(const int len) { while ( crp != 0 && S[S[crp].par].len >= len ) crp = S[crp].par; if ( crp == 0 ) crp = 1; } const void Transfer(const int len, const char ch) { crp = S[crp].trans[ch - 'a']; if ( crp == 0 ) crp = 1; Withdraw(len); } const void Insert(const char ch) { int x = ch - 'a'; np = ++size; S[np].len = S[p].len + 1; while ( p != 0 && !S[p].trans[x] ) S[p].trans[x] = np, p = S[p].par; if ( p == 0 ) S[np].par = 1; else { int q, nq; q = S[p].trans[x]; if ( S[q].len == S[p].len + 1 ) S[np].par = q; else { nq = ++size; S[nq] = S[q], S[nq].len = S[p].len + 1; S[np].par = S[q].par = nq; while ( p != 0 && S[p].trans[x] == q ) S[p].trans[x] = nq, p = S[p].par; } } p = np; } } SAM; string s; ll f[maxn], p, q; ll DP() { SAM.Insert(s[0]); f[0] = p; int l = 1, r = 0; for (int i = 1; i < (int)s.size(); ++i) { ++r; f[i] = f[i - 1] + p; while ( ( !SAM.Match(s[i]) || r - l + 1 > (i + 1) / 2 ) && l <= r ) { SAM.Insert(s[l++]); SAM.Withdraw(r - l); } SAM.Transfer(r - l + 1, s[i]); if (l <= r) { f[i] = min(f[i], f[i - (r - l + 1)] + q); } } SAM.Clear(); return f[s.size() - 1]; } int main() { std::ios::sync_with_stdio(0); std::cin.tie(0); std::cout.tie(0); while ( cin >> s >> p >> q ) { ll ans = DP(); cout << ans << ' ' ; } return 0; }
G:
题意为求分子分母均小于等于某个值n的第k大的最简分数。
1 #include <bits/stdc++.h> 2 3 typedef std::pair<long long, long long> Frac; 4 5 Frac operator + (Frac a, Frac b) { 6 long long y = a.second / std::__gcd(a.second, b.second) * b.second, 7 x = a.first * (y / a.second) + b.first * (y / b.second); 8 return {x, y}; 9 } 10 11 Frac operator /(Frac a, int b) { 12 long long x = a.first, y = a.second * b, 13 d = std::__gcd(x, y); 14 return {x / d, y / d}; 15 } 16 17 const int N = 1e6, XN = N + 11; 18 19 int prime[XN], mu[XN], mert[XN], pcnt; 20 21 void Prep() { 22 static bool notPrime[XN]; 23 mu[1] = 1; 24 for (int i = 2; i <= N; ++i) { 25 if (!notPrime[i]) { 26 prime[++pcnt] = i; 27 mu[i] = -1; 28 } 29 for (int j = 1; j <= pcnt && i * prime[j] <= N; ++j) { 30 notPrime[i * prime[j]] = 1; 31 if (i % prime[j] == 0) { 32 mu[i * prime[j]] = 0; 33 break; 34 } else 35 mu[i * prime[j]] = -mu[i]; 36 } 37 } 38 for (int i = 1; i <= N; ++i) 39 mert[i] = mert[i - 1] + mu[i]; 40 } 41 42 long long Sum(long long n, long long a, long long b, long long m) { 43 if (b == 0) 44 return n * (a / m); 45 else if (a >= m) 46 return n * (a / m) + Sum(n, a % m, b, m); 47 else if (b >= m) 48 return (n - 1) * n / 2 * (b / m) + Sum(n, a, b % m, m); 49 else 50 return Sum(((__int128)b * n + a) / m, (a + (__int128)b * n) % m, m, b); 51 } 52 53 long long Count(Frac x, int n) { 54 long long res = 0; 55 for (int l = 1, r; l <= n; l = r + 1) { 56 r = n / (n / l); 57 res += Sum(n / l + 1, 0, x.first, x.second) * (mert[r] - mert[l - 1]); 58 } 59 return res; 60 } 61 62 Frac Gen(long long a, long long b, int n, long long k) { 63 Frac l{0, 1}, mid{1, 1}, r{1, 0}, res{-1, -1}; 64 long long x = a, y = b; 65 while (x != y && std::max(mid.first, mid.second) <= n) { 66 if (a * mid.second < b * mid.first) 67 res = mid; 68 if (x < y) { 69 std::tie(l, mid, r) = std::make_tuple(l, std::make_pair(l.first + mid.first, l.second + mid.second), mid); 70 y -= x; 71 } else { 72 std::tie(l, mid, r) = std::make_tuple(mid, std::make_pair(mid.first + r.first, mid.second + r.second), r); 73 x -= y; 74 } 75 } 76 assert(Count(res, n) == k); 77 return res; 78 } 79 80 int main() { 81 std::ios::sync_with_stdio(0); 82 std::cin.tie(0); 83 Prep(); 84 int T; std::cin >> T; 85 while (T--) { 86 int n; long long k; 87 std::cin >> n >> k; 88 Frac l{0, 1}, r{1, 1}, pivot{-1, -1}; 89 for (int t = 40; t--;) { 90 Frac mid = (l + r) / 2; 91 if (Count(mid, n) < k) { 92 pivot = mid; 93 l = mid; 94 } else 95 r = mid; 96 } 97 auto Ans = Gen(pivot.first, pivot.second, n, k); 98 std::cout << Ans.first << '/' << Ans.second << ' '; 99 } 100 return 0; 101 }
H:
仙人掌相关题。分治+fft。
1 #include <bits/stdc++.h> 2 3 const int XN = (1 << 18) + 11, P = 998244353; 4 5 int Add(int x, int const &y) { 6 return (x += y) >= P ? x - P : x; 7 } 8 9 void AddBy(int &x, int const &y) { 10 ((x += y) >= P) && (x -= P); 11 } 12 13 int Minus(int x, int const &y) { 14 return (x -= y) < 0 ? x + P : x; 15 } 16 17 int Mul(long long x, int const &y) { 18 return x * y % P; 19 } 20 21 void MulBy(int &x, int const &y) { 22 x = (long long)x * y % P; 23 } 24 25 int Pow(long long base, int v) { 26 long long res; 27 for (res = 1; v; v >>= 1, (base *= base) %= P) 28 if (v & 1) 29 (res *= base) %= P; 30 return res; 31 } 32 33 int Inverse(int x) { 34 return Pow(x, P - 2); 35 } 36 37 int Make2(int x) { 38 return 1 << ((32 - __builtin_clz(x)) + ((x & (-x)) != x)); 39 } 40 41 void NTT(int a[], int n, int op) { 42 for (int i = 1, j = n >> 1; i < n - 1; ++i) { 43 if (i < j) 44 std::swap(a[i], a[j]); 45 int k = n >> 1; 46 while (k <= j) { 47 j -= k; 48 k >>= 1; 49 } 50 j += k; 51 } 52 for (int len = 2; len <= n; len <<= 1) { 53 int rt = Pow(3, (P - 1) / len); 54 for (int i = 0; i < n; i += len) { 55 int w = 1; 56 for (int j = i; j < i + len / 2; ++j) { 57 int u = a[j], t = Mul(a[j + len / 2], w); 58 a[j] = Add(u, t), a[j + len / 2] = Minus(u, t); 59 w = Mul(w, rt); 60 } 61 } 62 } 63 if (op == -1) { 64 std::reverse(a + 1, a + n); 65 int in = Inverse(n); 66 for (int i = 0; i < n; ++i) 67 a[i] = Mul(a[i], in); 68 } 69 } 70 71 void Contrb(int A[], int An, int B[], int Bn, int offset, int C[], int L, int R) { 72 if ((long long)An * Bn < 1000000) { 73 for (int i = 0; i < An; ++i) 74 for (int j = 0; j < Bn; ++j) { 75 int k = i + j; 76 if (L <= k + offset && k + offset <= R) 77 AddBy(C[k + offset], Mul(A[i], B[j])); 78 } 79 return; 80 } 81 static int a[XN], b[XN]; 82 int n = Make2(An + Bn - 1); 83 for (int i = 0; i < n; ++i) { 84 a[i] = i < An ? A[i] : 0; 85 b[i] = i < Bn ? B[i] : 0; 86 } 87 NTT(a, n, 1); NTT(b, n, 1); 88 for (int i = 0; i < n; ++i) 89 a[i] = Mul(a[i], b[i]); 90 NTT(a, n, -1); 91 for (int i = 0; i < n; ++i) 92 if (L <= i + offset && i + offset <= R) 93 AddBy(C[i + offset], a[i]); 94 } 95 96 int a[XN], b[XN], c[XN], d[XN], n, inv[XN]; 97 98 void DC(int L, int R) { 99 if (L == R) { 100 if (L == 1) 101 a[L] = 1; 102 else 103 MulBy(a[L], inv[L - 1]); 104 AddBy(b[L], a[L]); 105 AddBy(c[L], a[L]); 106 int x = Mul(L, Mul(Add(Add(b[L], c[L]), L % 2 == 0 ? b[L / 2] : 0), inv[2])); 107 for (int i = L; i <= n; i += L) 108 AddBy(d[i], x); 109 } else { 110 int M = (L + R) / 2; 111 DC(L, M); 112 auto Calc = [&](int L1, int R1, int L2, int R2) { 113 Contrb(a + L1, R1 - L1 + 1, d + L2, R2 - L2 + 1, L1 + L2, a, M + 1, R); 114 Contrb(a + L1, R1 - L1 + 1, b + L2, R2 - L2 + 1, L1 + L2, b, M + 1, R); 115 static int a2[XN]; 116 for (int i = L1; i <= R1; ++i) 117 a2[i] = i % 2 == 0 ? a[i / 2] : 0; 118 Contrb(a2 + L1, R1 - L1 + 1, c + L2, R2 - L2 + 1, L1 + L2, c, M + 1, R); 119 }; 120 if (L != 1) { 121 Calc(L, M, 1, R - L); 122 Calc(1, R - L, L, M); 123 } 124 Calc(L, M, L, M); 125 DC(M + 1, R); 126 } 127 } 128 129 int main() { 130 std::ios::sync_with_stdio(0); 131 std::cin.tie(0); 132 std::cin >> n; 133 for (int i = 1; i <= n; ++i) 134 inv[i] = Pow(i, P - 2); 135 DC(1, n); 136 for (int i = 1; i <= n; ++i) 137 std::cout << a[i] << ' '; 138 return 0; 139 }
I:
一位位地构造答案字符串,每次贪心地加能加入的最小的字符(判断能否加入只要判断加入之后原字符串剩下的后缀中的每种字符的数目能否足够满足条件)。
1 #include <bits/stdc++.h> 2 using namespace std; 3 #define rep(i, j, k) for (int i = int(j); i <= int(k); ++ i) 4 #define dwn(i, j, k) for (int i = int(j); i >= int(k); -- i) 5 const int N = 1e5 + 7; 6 char s[N], s1[N]; 7 int k, n, cnt[N][26], l[26], r[26], used[26]; 8 vector<int> g[26]; 9 int main() { 10 while (~scanf("%s%d", s, &k)) { 11 memset(used, 0, sizeof(used)); 12 rep(i, 0, 25) scanf("%d%d", l + i, r + i); 13 n = strlen(s); 14 memset(cnt[n], 0, sizeof(cnt[n])); 15 for (int i = 0; i < 26; ++i) 16 g[i].clear(); 17 dwn(i, n - 1, 0) rep(j, 0, 25) cnt[i][j] = cnt[i + 1][j] + (s[i] == 'a' + j); 18 rep(i, 0, n - 1) g[s[i] - 'a'].push_back(i); 19 // for (int i: g[0]) cout << i << " "; cout << endl; 20 // for (int i: g[1]) cout << i << " ";cout << endl; 21 vector<int>::iterator head[26]; 22 rep(i, 0, 25) head[i] = g[i].begin(); 23 int last = -1; 24 rep(i, 0, k - 1) { 25 bool f1 = 0; 26 rep(j, 0, 25) { 27 if (used[j] == r[j]) continue; 28 while (head[j] != g[j].end() && (*head[j]) <= last) head[j] ++; 29 if (head[j] == g[j].end()) continue; 30 used[j] ++; 31 bool flag = 1; 32 int pos = *head[j], sum = 0; 33 34 rep(t, 0, 25) { 35 if (cnt[pos + 1][t] + used[t] < l[t]) flag = 0; 36 sum += max(l[t] - used[t], 0); 37 } 38 if (sum > k - i - 1) flag = 0; 39 sum = 0; 40 rep(t, 0, 25) { 41 sum += min(cnt[pos + 1][t], r[t] - used[t]); 42 } 43 if (sum < k - i - 1) flag = 0; 44 // cout << i << " " << j << " " << flag << endl; 45 if (!flag) used[j] --; 46 else { 47 s1[i] = 'a' + j; 48 f1 = 1; 49 last = pos; 50 break; 51 } 52 } 53 if (!f1) { 54 printf("-1 "); 55 goto end; 56 } 57 } 58 /*int cc[26]; 59 rep(i, 0, 25) cc[i] = 0; 60 rep(i, 0, k - 1) cc[s1[i] - 'a'] ++; 61 rep(i, 0, 25) { 62 if (cc[i] < l[i] || cc[i] > r[i]) { 63 cout << i << endl; 64 cout << cc[i] << " " << l[i] << " " << r[i] << endl; 65 } 66 }*/ 67 s1[k] = 0; 68 printf("%s ", s1); 69 end:; 70 } 71 return 0; 72 }
J:
记忆化搜索。
1 #include <iostream> 2 #include <cstdio> 3 #include <cstdlib> 4 #include <cmath> 5 #include <cstring> 6 #include <string> 7 #include <algorithm> 8 9 using namespace std; 10 11 const int maxn = 105; 12 13 long long mod = 998244353; 14 15 int n, m, t; 16 17 long long f[maxn][maxn][maxn]; 18 19 int a[maxn]; 20 int b[maxn]; 21 int pa[maxn]; 22 int pb[maxn]; 23 bool vis[maxn]; 24 25 int read(){ 26 int x; 27 scanf("%d", &x); 28 return x; 29 } 30 31 int dfs(int x, int l, int r){ 32 if(f[x][l][r] != -1)return 0; 33 f[x][l][r] = 0; 34 if(l == r){ 35 f[x][l][r] = 1; 36 if(a[x] != b[l]){ 37 if(a[x] and b[l]){ 38 f[x][l][r] = 0; 39 }else if(a[x] and pb[a[x]] and pb[a[x]] != l){ 40 f[x][l][r] = 0; 41 }else if(b[l] and pa[b[l]] and pa[b[l]] != x){ 42 f[x][l][r] = 0; 43 } 44 } 45 return 0; 46 } 47 48 if(r + 1 == l)f[x][l][r] = 1; 49 if(r < l)return 0; 50 51 if(a[x]){ 52 if(pb[a[x]]){ 53 if(pb[a[x]] < l or pb[a[x]] > r){ 54 f[x][l][r] = 0; 55 }else{ 56 dfs(x + 1, l, pb[a[x]] - 1); 57 dfs(x + pb[a[x]] - l + 1, pb[a[x]] + 1, r); 58 f[x][l][r] = f[x + 1][l][pb[a[x]] - 1] * f[x + pb[a[x]] - l + 1][pb[a[x]] + 1][r] % mod; 59 } 60 return 0; 61 } 62 63 int maxx = l; 64 65 for(int i=l;i<=r;i++){ 66 if(pa[b[i]]){ 67 if(pa[b[i]] < x or pa[b[i]] > x + r - l)break; 68 maxx = max(maxx, l + pa[b[i]] - x); 69 } 70 if(b[i])continue; 71 if(i < maxx)continue; 72 dfs(x + 1, l, i - 1); 73 dfs(x + i - l + 1, i + 1, r); 74 f[x][l][r] = (f[x][l][r] + f[x + 1][l][i - 1] * f[x + i - l + 1][i + 1][r]) % mod; 75 } 76 return 0; 77 } 78 79 int maxx = l; 80 81 for(int i=l;i<=r;i++){ 82 if(pa[b[i]]){ 83 if(pa[b[i]] < x or pa[b[i]] > x + r - l)break; 84 maxx = max(maxx, l + pa[b[i]] - x); 85 } 86 if(i < maxx)continue; 87 dfs(x + 1, l, i - 1); 88 dfs(x + i - l + 1, i + 1, r); 89 f[x][l][r] = (f[x][l][r] + f[x + 1][l][i - 1] * f[x + i - l + 1][i + 1][r]) % mod; 90 } 91 92 return 0; 93 } 94 95 int main(){ 96 int i, j; 97 long long ans = 0; 98 int T;std::cin>>T; 99 while(T--) { 100 scanf("%d", &n); 101 long long cnt=0; 102 memset(pa,0,sizeof(pa)); 103 memset(pb,0,sizeof(pb)); 104 memset(vis,0,sizeof(vis)); 105 for(i=1;i<=n;i++){ 106 a[i] = read(); 107 if(a[i])pa[a[i]] = i; 108 vis[a[i]] = true; 109 } 110 111 for(i=1;i<=n;i++){ 112 b[i] = read(); 113 if(b[i])pb[b[i]] = i; 114 vis[b[i]] = true; 115 } 116 117 memset(f, -1, sizeof(f)); 118 119 dfs(1, 1, n); 120 ans = f[1][1][n]; 121 122 for(i=1;i<=n;i++){ 123 if(!vis[i])cnt++; 124 } 125 126 for(i=1;i<=cnt;i++){ 127 ans = ans * i % mod; 128 } 129 130 printf("%lld ", ans); 131 } 132 return 0; 133 }
K:
数论反演。
1 #include <bits/stdc++.h> 2 3 struct Istream { 4 template <class T> 5 Istream &operator >>(T &x) { 6 static char ch; static bool neg; 7 for (ch = neg = 0; ch < '0' || '9' < ch; neg |= ch == '-', ch = getchar()); 8 for (x = 0; '0' <= ch && ch <= '9'; (x *= 10) += ch - '0', ch = getchar()); 9 x = neg ? -x : x; 10 return *this; 11 } 12 } fin; 13 14 struct Ostream { 15 template <class T> 16 Ostream &operator <<(T x) { 17 x < 0 && (putchar('-'), x = -x); 18 static char stack[233]; static int top; 19 for (top = 0; x; stack[++top] = x % 10 + '0', x /= 10); 20 for (top == 0 && (stack[top = 1] = '0'); top; putchar(stack[top--])); 21 return *this; 22 } 23 24 Ostream &operator <<(char ch) { 25 putchar(ch); 26 return *this; 27 } 28 } fout; 29 30 const int N = 1e7, XN = N + 11, P = 998244353; 31 32 int Add(int x, int const &y) { 33 return (x += y) >= P ? x - P : x; 34 } 35 36 int Minus(int x, int const &y) { 37 return (x -= y) < 0 ? x + P : x; 38 } 39 40 int Mul(long long x, int const &y) { 41 return x * y % P; 42 } 43 44 int prime[XN], phi[XN], pcnt; 45 void Prep() { 46 static bool notPrime[XN]; 47 phi[1] = 1; 48 for (int i = 2; i <= N; ++i) { 49 if (!notPrime[i]) { 50 prime[++pcnt] = i; 51 phi[i] = i - 1; 52 } 53 for (int j = 1; j <= pcnt && i * prime[j] <= N; ++j) { 54 notPrime[i * prime[j]] = 1; 55 if (i % prime[j] == 0) { 56 phi[i * prime[j]] = phi[i] * prime[j]; 57 break; 58 } else 59 phi[i * prime[j]] = phi[i] * phi[prime[j]]; 60 } 61 } 62 } 63 64 int Sum1(long long x) { 65 return x * (x + 1) / 2 % P; 66 } 67 68 int Sum2(long long x) { 69 return (x * (x + 1)) % (6ll * P) * (2 * x + 1) / 6 % P; 70 } 71 72 int Calc(int a, __int128 L, __int128 R) { 73 int res = 0; 74 for (int d = 1; 1LL * d * d <= a; ++d) 75 if (a % d == 0) { 76 res = Add(res, Mul((R / d - L / d) % P, phi[d])); 77 if (a != d * d) 78 res = Add(res, Mul((R / (a / d) - L / (a / d)) % P, phi[a / d])); 79 } 80 return res; 81 } 82 83 int main() { 84 //freopen("input","r",stdin); 85 Prep(); 86 int T; 87 fin >> T; 88 while (T--) { 89 __int128 n; fin >> n; 90 if (n <= 7) { 91 fout << n << ' '; 92 } else { 93 int r; for (r = 1; (__int128)(r + 2) * (r + 2) * (r + 2) - 1 <= n; ++r); 94 int Ans = Calc(r + 1, (__int128)(r + 1) * (r + 1) * (r + 1) - 1, n); 95 for (int T = 1; T <= r; ++T) 96 Ans = Add(Ans, Mul(phi[T], Add(Add(Mul(3 * T, Sum2(r / T)), Mul(3, Sum1(r / T))), r / T))); 97 fout << Ans << ' '; 98 } 99 } 100 return 0; 101 }
L:
推式子数论题。NTT。
1 #include <bits/stdc++.h> 2 3 const int XN = 2e6 + 11, P = 998244353; 4 5 int Pow(long long base, int v) { 6 long long res; 7 for (res = 1; v; v >>= 1, (base *= base) %= P) 8 if (v & 1) 9 (res *= base) %= P; 10 return res; 11 } 12 13 int D(int x) { 14 ((x >= P) && (x -= P)) || ((x < 0) && (x += P)); 15 return x; 16 } 17 18 void NTT(int a[], int n, int op) { 19 for (int i = 1, j = n >> 1; i < n - 1; ++i) { 20 if (i < j) 21 std::swap(a[i], a[j]); 22 int k = n >> 1; 23 while (k <= j) { 24 j -= k; 25 k >>= 1; 26 } 27 j += k; 28 } 29 for (int len = 2; len <= n; len <<= 1) { 30 int rt = Pow(3, (P - 1) / len); 31 for (int i = 0; i < n; i += len) { 32 int w = 1; 33 for (int j = i; j < i + len / 2; ++j) { 34 int u = a[j], t = 1LL * a[j + len / 2] * w % P; 35 a[j] = D(u + t), a[j + len / 2] = D(u - t); 36 w = 1LL * w * rt % P; 37 } 38 } 39 } 40 if (op == -1) { 41 std::reverse(a + 1, a + n); 42 int in = Pow(n, P - 2); 43 for (int i = 0; i < n; ++i) 44 a[i] = 1LL * a[i] * in % P; 45 } 46 } 47 48 std::vector<int> Conv(std::vector<int> const &A, std::vector<int> const &B, int N) { 49 static int a[XN], b[XN]; 50 auto Make2 = [](int x)->int { 51 return 1 << ((32 - __builtin_clz(x)) + ((x & (-x)) != x)); 52 }; 53 int n = Make2(A.size() + B.size() - 1); 54 for (int i = 0; i < n; ++i) { 55 a[i] = i < A.size() ? A[i] : 0; 56 b[i] = i < B.size() ? B[i] : 0; 57 } 58 NTT(a, n, 1); NTT(b, n, 1); 59 for (int i = 0; i < n; ++i) 60 a[i] = 1LL * a[i] * b[i] % P; 61 NTT(a, n, -1); 62 std::vector<int> C(N); 63 for (int i = 0; i < N; i++) 64 C[i] = a[i]; 65 return C; 66 } 67 68 const int M = 2e6, XM = M + 11; 69 70 int fact[XM], ifact[XM]; 71 72 int C(int n, int m) { 73 return m <= n ? (long long)fact[n] * ifact[m] % P * ifact[n - m] % P : 0; 74 } 75 76 int main() { 77 std::ios::sync_with_stdio(0); 78 std::cin.tie(0); 79 fact[0] = 1; 80 for (int i = 1; i <= M; ++i) 81 fact[i] = (long long)fact[i - 1] * i % P; 82 ifact[M] = Pow(fact[M], P - 2); 83 for (int i = M - 1; i >= 0; --i) 84 ifact[i] = (long long)ifact[i + 1] * (i + 1) % P; 85 int T; std::cin >> T; 86 while (T--) { 87 int n, m; std::cin >> n >> m; 88 89 std::vector<int> a(n); 90 for (int i = 0; i < n; ++i) { 91 std::cin >> a[i]; 92 } 93 94 int cnt[] = {0, 0, 0, 0}; 95 for (int i = 1; i <= m; ++i) { 96 int x; std::cin >> x; 97 cnt[x]++; 98 } 99 100 for (int c = 1; c <= 3; ++c) if (cnt[c]) { 101 std::vector<int> h(n); 102 for (int i = 0; i * c < n; ++i) 103 h[i * c] = C(cnt[c] - 1 + i, i); 104 a = Conv(h, a, n); 105 } 106 long long Ans = 0; 107 for (int i = 0; i < n; ++i) 108 Ans ^= 1LL * (i + 1) * a[i]; 109 std::cout << Ans << ' '; 110 } 111 return 0; 112 }
M:
经过转化可以变成判断凸包是否相交的题。
1 #include <cstdio> 2 #include <vector> 3 #include <iostream> 4 #include <algorithm> 5 using namespace std; 6 7 const int N = 105; 8 9 int n; 10 11 int sgn(long long x) { 12 return (x > 0) - (x < 0); 13 } 14 15 struct P { 16 long long d[3]; 17 long long &operator[](int x) { 18 return d[x]; 19 } 20 P () {} 21 P (long long a, long long b, long long c) { 22 d[0] = a; d[1] = b; d[2] = c; 23 } 24 }; 25 26 struct node { 27 P x; 28 int y; 29 } p[N]; 30 31 P operator+(P a, P b) { 32 P c; 33 for (int i = 0; i < 3; i++) 34 c[i] = a[i] + b[i]; 35 return c; 36 } 37 38 P operator-(P a, P b) { 39 P c; 40 for (int i = 0; i < 3; i++) 41 c[i] = a[i] - b[i]; 42 return c; 43 } 44 45 P operator*(int a, P b) { 46 P c; 47 for (int i = 0; i < 3; i++) 48 c[i] = a * b[i]; 49 return c; 50 } 51 52 bool operator<(P a, P b) { 53 return a[1] < b[1] || (a[1] == b[1] && a[2] < b[2]); 54 } 55 56 long long operator*(P a, P b) { 57 return a[1] * b[2] - a[2] * b[1]; 58 } 59 60 long long operator^(P a, P b) { 61 return a[1] * b[1] + a[2] * b[2]; 62 } 63 64 long long det(P a, P b, P c) { 65 return (b - a) * (c - a); 66 } 67 68 struct L { 69 P a, b; 70 L () {} 71 L (P x, P y) { 72 a = x; b = y; 73 } 74 }; 75 76 bool onSeg(P p, L s) { 77 return sgn(det(p, s.a, s.b)) == 0 && sgn((s.a - p) ^ (s.b - p)) <= 0; 78 } 79 80 vector<P> convex(vector<P> p) { 81 vector<P> ans, S; 82 for (int i = 0; i < p.size(); i++) { 83 while (S.size() >= 2 84 && sgn(det(S[S.size() - 2], S.back(), p[i])) <= 0) 85 S.pop_back(); 86 S.push_back(p[i]); 87 } 88 ans = S; 89 S.clear(); 90 for (int i = (int)p.size() - 1; i >= 0; i--) { 91 while (S.size() >= 2 92 && sgn(det(S[S.size() - 2], S.back(), p[i])) <= 0) 93 S.pop_back(); 94 S.push_back(p[i]); 95 } 96 for (int i = 1; i + 1 < S.size(); i++) 97 ans.push_back(S[i]); 98 return ans; 99 } 100 101 bool PointInPolygon(P p, vector<P> poly) { 102 int cnt = 0; 103 for (int i = 0; i < poly.size(); i++) { 104 if (onSeg(p, L(poly[i], poly[(i + 1) % poly.size()]))) return true; 105 int k = sgn(det(poly[i], poly[(i + 1) % poly.size()], p)); 106 int d1 = sgn(poly[i][2] - p[2]); 107 int d2 = sgn(poly[(i + 1) % poly.size()][2] - p[2]); 108 if (k > 0 && d1 <= 0 && d2 > 0) cnt++; 109 if (k < 0 && d2 <= 0 && d1 > 0) cnt--; 110 } 111 if (cnt != 0) return true; 112 return false; 113 } 114 115 bool SegmentIntersection(L l1, L l2) { 116 long long c1 = det(l1.a, l1.b, l2.a), c2 = det(l1.a, l1.b, l2.b); 117 long long c3 = det(l2.a, l2.b, l1.a), c4 = det(l2.a, l2.b, l1.b); 118 if (sgn(c1) * sgn(c2) < 0 && sgn(c3) * sgn(c4) < 0) return true; 119 if (sgn(c1) == 0 && onSeg(l2.a, l1)) return true; 120 if (sgn(c2) == 0 && onSeg(l2.b, l1)) return true; 121 if (sgn(c3) == 0 && onSeg(l1.a, l2)) return true; 122 if (sgn(c4) == 0 && onSeg(l1.b, l2)) return true; 123 return false; 124 } 125 126 bool ConvexHullDivide(vector<P> p1, vector<P> p2) { 127 for (int i = 0; i < p1.size(); i++) 128 if (PointInPolygon(p1[i], p2)) 129 return false; 130 for (int i = 0; i < p2.size(); i++) 131 if (PointInPolygon(p2[i], p1)) 132 return false; 133 for (int i = 0; i < p1.size(); i++) 134 for (int j = 0; j < p2.size(); j++) 135 if (SegmentIntersection(L(p1[i], p1[(i + 1) % p1.size()]), L(p2[j], p2[(j + 1) % p2.size()]))) 136 return false; 137 return true; 138 } 139 140 bool check() { 141 vector<P> p1, p2; 142 for (int i = 1; i <= n; i++) { 143 if (p[i].y == 1) 144 p1.push_back(p[i].x); 145 else 146 p2.push_back(p[i].x); 147 } 148 vector<P> c1, c2; 149 c1 = convex(p1); 150 c2 = convex(p2); 151 if (ConvexHullDivide(c1, c2)) return true; 152 return false; 153 } 154 155 int f(P w, P x) { 156 long long sum = 0; 157 for (int i = 0; i < 3; i++) 158 sum += w[i] * x[i]; 159 return sgn(sum); 160 } 161 162 void PLA() { 163 P w = P(0, 0, 0); 164 int i = 1, cnt = 0; 165 long long cc = 0; 166 while (true) { 167 cc++; 168 if (f(w, p[i].x) != p[i].y) { 169 w = w + p[i].y * p[i].x; 170 cnt = 0; 171 } else { 172 if (++cnt == n) break; 173 } 174 i = i + 1; 175 if (i > n) i -= n; 176 } 177 cout << cc << endl; 178 } 179 180 int main() { 181 int testcase; 182 cin >> testcase; 183 while (testcase--) { 184 cin >> n; 185 for (int i = 1; i <= n; i++) { 186 cin >> p[i].x[1] >> p[i].x[2] >> p[i].y; 187 p[i].x[0] = 1; 188 } 189 if (!check()) 190 puts("Infinite loop!"); 191 else { 192 puts("Successful!"); 193 } 194 } 195 return 0; 196 }
隔壁队通过不停地random x1和x2来初步判断b的可能取值范围,也一样过了。天秀。
1 #include<bits/stdc++.h> 2 using namespace std; 3 #define ll long long 4 #define mp(a,b) make_pair(a,b) 5 #define ff first 6 #define ss second 7 typedef pair<int,int> pii; 8 int a[110],b[110],c[110]; 9 int main(){ 10 int t;scanf("%d",&t); 11 while(t--){ 12 int n;scanf("%d",&n); 13 for(int i=1;i<=n;i++) 14 scanf("%d%d%d",&a[i],&b[i],&c[i]); 15 int ok=0; 16 for(int p=1;p<=1500;p++){ 17 int w1=2*rand()-RAND_MAX,w2=2*rand()-RAND_MAX; 18 ll minb=-1e18,maxb=1e18; 19 for(int i=1;i<=n;i++){ 20 ll s=w1*a[i]+w2*b[i]; 21 if(c[i]==1)minb=max(minb,1-s); 22 else maxb=min(maxb,1-s); 23 } 24 if(minb<=maxb){ 25 ok++;break; 26 } 27 } 28 if(!ok)printf("Infinite loop! "); 29 else printf("Successful! "); 30 } 31 }