可能会有人问“你的杭电多校4呢?”。别问,问就是在写了.jpg
题目链接:http://acm.hdu.edu.cn/contests/contest_show.php?cid=852
D:
把所有函数按零点位置排序,然后从左往右检查每对相邻零点形成的区间的解,并验证之。

1 /* basic header */ 2 #include <bits/stdc++.h> 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 = 1e5 + 10; 21 struct Function { 22 ll a, b; 23 Function(int _a = 1, int _b = 0): a(_a), b(_b) { 24 if (a < 0) a = -a, b = -b; 25 } 26 void simplicate() { 27 if (!b) a = 1; 28 else { 29 ll gg = __gcd(a, abs(b)); 30 a /= gg, b /= gg; 31 } 32 } 33 bool operator<(const Function &rhs) const { 34 return b * rhs.a < a * rhs.b; 35 } 36 bool operator<=(const Function &rhs) const { 37 return b * rhs.a <= a * rhs.b; 38 } 39 bool operator==(const Function &rhs) const { 40 return b * rhs.a == a * rhs.b; 41 } 42 } f[maxn]; 43 int tot; 44 45 void solve() { 46 int n; ll c; scanf("%d%lld", &n, &c); tot = 0; 47 for (int i = 0; i < n; i++) { 48 int a, b; scanf("%d%d", &a, &b); 49 b = -b; 50 if (!a) c -= abs(b); 51 else { 52 if (a < 0) a = -a, b = -b; 53 f[tot++] = Function(a, b); 54 } 55 } 56 if (!tot) { 57 if (!c) puts("-1"); else puts("0"); 58 return; 59 } 60 sort(f, f + tot); 61 vector<Function> func; 62 ll sumA = 0, sumB = 0; 63 for (int i = 0; i < tot; i++) 64 sumA += f[i].a, sumB += f[i].b; 65 { 66 Function res(sumA, c + sumB); 67 if (f[tot - 1] <= res) func.pb(res); 68 } 69 for (int i = tot - 1; i >= 0; i--) { 70 sumA -= f[i].a * 2, sumB -= f[i].b * 2; 71 if (!sumA) { 72 if (!(sumB + c)) { 73 if (f[i - 1] < f[i]) { 74 puts("-1"); 75 return; 76 } 77 } 78 continue; 79 } 80 Function res(sumA, c + sumB); 81 if (i) { 82 if (res <= f[i] && f[i - 1] <= res) 83 func.pb(res); 84 } else if (res <= f[i]) func.pb(res); 85 } 86 rep0(i, 0, (int)func.size()) func[i].simplicate(); 87 sort(func.begin(), func.end()); 88 func.resize(distance(func.begin(), unique(func.begin(), func.end()))); 89 printf("%d", (int)func.size()); 90 for (auto i : func) printf(" %lld/%lld", i.b, i.a); 91 puts(""); 92 } 93 int main() { 94 int caseNum; scanf("%d", &caseNum); 95 while (caseNum--) solve(); 96 return 0; 97 }
E:
虽然n!在n较大时会增长得很快,但这题k最大只有1e4,所以可以通过暴力dfs枚举答案。
答案的规律很显然,就是n!的全排列,然后按首元素从大到小,后面的元素从小到大排序的结果。

1 /* basic header */ 2 #include <bits/stdc++.h> 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 = 10; 21 int n, k, d[maxn], vis[maxn], tt = 0; 22 23 int dfs(int currBit, int lowPoint, int highPoint) { 24 if (currBit == n) { 25 if (!(--k)) { 26 vector<int>ans; 27 for (int i = 0; i < n; i++) ans.pb(d[i] - lowPoint + 1); 28 rep0(i, 0, (int)ans.size()) { 29 printf("%d", ans[i]); 30 if (i != (int)ans.size() - 1) printf(" "); else puts(""); 31 } 32 return 1; 33 } 34 return 0; 35 } 36 for (int i = highPoint - n + 1; i <= lowPoint + n - 1; i++) { 37 if (vis[i]) continue; 38 vis[i] = 1; d[currBit] = i; 39 if (dfs(currBit + 1, min(lowPoint, i), max(highPoint, i))) { 40 vis[i] = 0; return 1; 41 } 42 vis[i] = 0; 43 } 44 return 0; 45 } 46 47 int main() { 48 int t; scanf("%d", &t); 49 while (t--) { 50 tt++; 51 scanf("%d%d", &n, &k); 52 d[0] = n, vis[n] = 1; 53 dfs(1, n, n); 54 vis[n] = 0; 55 } 56 return 0; 57 }
F:
队友一眼exKMP题,我还没反应过来。还因为直接cin白给了一发,不应该。

1 #include<iostream> 2 #include<algorithm> 3 #include<cstdlib> 4 #include<cstdio> 5 #include<queue> 6 #include<cstring> 7 8 using namespace std; 9 10 const int maxn = 2000000; 11 char s[maxn]; 12 int Next[maxn]; 13 typedef long long ll; 14 void pre_EKMP(int m) { 15 Next[0] = m; 16 int j = 0; 17 while (j + 1 < m && s[j] == s[j + 1]) j++; 18 Next[1] = j; 19 int k = 1; 20 for (int i = 2; i < m; i++) { 21 int p = Next[k] + k - 1; 22 int L = Next[i - k]; 23 if (i + L < p + 1) { 24 Next[i] = L; 25 } else { 26 j = max(0, p - i + 1); 27 while (i + j < m && s[i + j] == s[j]) j++; 28 Next[i] = j; 29 k = i; 30 } 31 } 32 } 33 int main() { 34 ios::sync_with_stdio(false); 35 cin.tie(0); 36 cout.tie(0); 37 int T; 38 cin >> T; 39 while (T--) { 40 cin >> s; 41 int len = strlen(s); 42 pre_EKMP(len); 43 ll ans = 0; 44 for (int i = 1; i < len; i++) { 45 ans += Next[i]; 46 if (i + Next[i] < len) { 47 ans++; 48 } 49 } 50 cout << ans << endl; 51 } 52 return 0; 53 }
G:
对n==10和n==11的情况打个表就很清楚了
对于不在顶点处的元素,显然a[i][j]=a[i][j-1]+a[i][j-3];对于a[1][n]有a[1][n]=a[1][n+1]。

1 /* basic header */ 2 #include <bits/stdc++.h> 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 = 1e5 + 10, mod = 998244353; 21 int t, a[maxn]; 22 23 int main() { 24 a[1] = 0, a[2] = 1, a[3] = 1; 25 for (int i = 4; i < maxn; i++) a[i] = (a[i - 1] + a[i - 3]) % mod; 26 scanf("%d", &t); 27 while (t--) { 28 int n, x, y; scanf("%d%d%d", &n, &x, &y); 29 if (x > y) swap(x, y); 30 int fixY = x != 1 ? y - x : y; 31 if (y != n) printf("%d ", a[fixY]); else printf("%d ", a[fixY + 1]); 32 } 33 return 0; 34 }