1001 Is Derek lying?
不会
1002 hash
小格子每行hash,大格子里一定间隔枚举至少会有一个有的
间隔没算随便取的,取小了就T了,找到一个后也没check整个就过了
1 #include <iostream> 2 #include <cstdio> 3 #include <unordered_map> 4 using namespace std; 5 typedef long long LL; 6 typedef pair<int, int> pii; 7 unordered_map<LL, pii> M; 8 char s[1111]; 9 int G[1111][1111]; 10 11 inline unsigned sfr(unsigned h, unsigned x) { 12 return h >> x; 13 } 14 int f(LL i, LL j) { 15 LL w = i * 1000000ll + j; 16 int h = 0; 17 for(int k = 0; k < 5; ++k) { 18 h += (int) ((w >> (8 * k)) & 255); 19 h += (h << 10); 20 h ^= sfr(h, 6); 21 } 22 h += h << 3; 23 h ^= sfr(h, 11); 24 h += h << 15; 25 return sfr(h, 27) & 1; 26 } 27 28 int main(void) 29 { 30 int T; 31 scanf("%d", &T); 32 for(int kase = 1; kase <= T; kase++) 33 { 34 M.clear(); 35 for(int i = 1; i <= 1000; i++) 36 { 37 scanf("%s", s + 1); 38 for(int j = 1; j <= 1000; j++) G[i][j] = s[j] - '0'; 39 LL h = 0; 40 for(int j = 1; j < 64; j++) h = (h << 1) + G[i][j]; 41 for(int j = 1; j + 63 <= 1000; j++) h = (h << 1) + G[i][j+63], M[h] = pii(i, j); 42 } 43 int ok = 0; 44 for(int i = 1; i <= 1000000; i += 1000) 45 { 46 for(int j = 1; j + 63 <= 1000000; j += 1000) 47 { 48 LL h = 0; 49 for(int k = j; k <= j + 63; k++) h = (h << 1) + f(i, k); 50 if(M.find(h) != M.end()) 51 { 52 pii ans = M[h]; 53 int x = ans.first, y = ans.second; 54 printf("Case #%d :%d %d ", kase, i - x + 1, j - y + 1); 55 ok = 1; break; 56 } 57 } 58 if(ok) break; 59 } 60 } 61 return 0; 62 }
1003 Maximum Sequence
贪心,显然前面大要好
1 #include <iostream> 2 #include <cstdio> 3 #include <algorithm> 4 using namespace std; 5 typedef long long LL; 6 const LL mod = 1e9 + 7; 7 const int maxn = 3e5 + 10; 8 int a[maxn], M[maxn], b[maxn]; 9 10 int main(void) 11 { 12 int n; 13 while(~scanf("%d", &n)) 14 { 15 for(int i = 1; i <= n; i++) scanf("%d", a + i), a[i] -= i; 16 M[n] = a[n]; 17 for(int i = n - 1; i; i--) M[i] = max(M[i+1], a[i]); 18 for(int i = 1; i <= n; i++) scanf("%d", b + i); 19 sort(b + 1, b + 1 + n); 20 int tmp = 0; 21 LL sum = 0; 22 for(int i = n + 1; i <= n + n; i++) 23 { 24 int x = max(tmp, M[b[i-n]]); 25 tmp = max(tmp, x - i); 26 sum = sum + x; 27 } 28 printf("%lld ", sum % mod); 29 } 30 return 0; 31 }
1004 Puzzle
没意思的结论题
1 #include <iostream> 2 #include <cstdio> 3 using namespace std; 4 5 int main(void) 6 { 7 int T; 8 scanf("%d", &T); 9 while(T--) 10 { 11 int n, m, p; 12 scanf("%d %d %d", &n, &m, &p); 13 int cur = n * m - 1, ans = 0; 14 while(cur > p) 15 { 16 int tmp = (cur - 1) / p + 1; 17 cur -= tmp; 18 ans += tmp * (tmp - 1) / 2 * (p - 1); 19 } 20 puts(ans % 2 ? "NO" : "YES"); 21 } 22 return 0; 23 }
1005 Sdjpx Is Happy
迷之复杂度的暴力
1 #include <iostream> 2 #include <cstdio> 3 using namespace std; 4 int a[5555], p[5555], dp[5555][5555], m[5555][5555], M[5555][5555]; 5 6 int main(void) 7 { 8 int T; 9 scanf("%d", &T); 10 while(T--) 11 { 12 int n; 13 scanf("%d", &n); 14 for(int i = 1; i <= n; i++) scanf("%d", a + i); 15 for(int i = 1; i <= n; i++) 16 { 17 m[i][i] = M[i][i] = a[i]; 18 for(int j = i + 1; j <= n; j++) m[i][j] = min(m[i][j-1], a[j]), M[i][j] = max(M[i][j-1], a[j]); 19 } 20 for(int i = 1; i <= n; i++) dp[i][i] = 1, p[i] = i; 21 for(int l = 2; l <= n; l++) 22 { 23 for(int s = 1; s + l - 1 <= n; s++) 24 { 25 int e = s + l - 1; 26 if(M[s][e] - m[s][e] == e - s) 27 { 28 if(m[s][e] < m[s][p[s]]) dp[s][e] = 1; 29 else dp[s][e] = dp[s][p[s]] + dp[p[s]+1][e]; 30 p[s] = e; 31 } 32 else dp[s][e] = 0; 33 } 34 } 35 int ans = dp[1][n]; 36 for(int i = 1; i <= n; i++) 37 { 38 for(int j = i; j <= n; j++) 39 { 40 if(!dp[i][j]) continue; 41 if(i > 1 && (!dp[1][i-1] || m[1][i-1] != 1)) continue; 42 int nj = M[i][j]; 43 if(nj < n && (!dp[nj+1][n] || M[nj+1][n] != n)) continue; 44 for(int ni = nj; ni > j; ni--) 45 if(dp[ni][nj] && m[ni][nj] == i) ans = max(ans, dp[1][i-1] + dp[j+1][ni-1] + dp[nj+1][n] + 2); 46 } 47 } 48 printf("%d ", ans); 49 } 50 return 0; 51 }
据说是可以on的
首先看不交换最多可以划分几段,这个扫一遍维护min,max即可求得位置,假设划分了m段
后面交换两端必然是选择上面m段中的一段,假设这一段是[l1, r2],一定是选择[l1, r1][l2, r2]这两段交换,然后再分割[r1 + 1, l2 - 1]这个区间
后面一步不知道怎么线性
1006 Funny Function
特征根求解等比数列求和
1 #include <iostream> 2 #include <cstdio> 3 using namespace std; 4 typedef long long LL; 5 const LL mod = 1e9 + 7; 6 7 LL qpow(LL a, LL b) 8 { 9 LL ret = 1LL; 10 while(b) 11 { 12 if(b & 1) ret = ret * a % mod; 13 a = a * a % mod; 14 b >>= 1; 15 } 16 return ret; 17 } 18 19 LL inv(LL x) 20 { 21 return qpow(x, mod - 2); 22 } 23 24 int main(void) 25 { 26 int T; 27 scanf("%d", &T); 28 while(T--) 29 { 30 LL N, M; 31 scanf("%lld %lld", &N, &M); 32 LL a = 1, b = 2; 33 if(N % 2 == 0) a = 0; 34 LL e = (qpow(2, N) + mod - 1) % mod; 35 b = b * qpow(e, M - 1) % mod; 36 LL ans = (a + b) * inv(3) % mod; 37 printf("%lld ", ans); 38 } 39 return 0; 40 }
1007 If the starlight never fade
1008 To my boyfriend
想清楚后觉得题解很蠢 每个格子标号后 数字贡献算在标号最小的格子上面
枚举每种颜色的每个格子 再枚举上面可延伸的高度 左右双指针两边扫 下面随便取
1 #include <iostream> 2 #include <cstdio> 3 #include <vector> 4 using namespace std; 5 typedef pair<int, int> pii; 6 typedef long long LL; 7 int G[111][111], low[111]; 8 vector<pii> e[11111]; 9 10 int main(void) 11 { 12 int T; 13 scanf("%d", &T); 14 while(T--) 15 { 16 int n, m; 17 scanf("%d %d", &n, &m); 18 for(int i = 1; i <= n; i++) 19 for(int j = 1; j <= m; j++) 20 scanf("%d", &G[i][j]); 21 for(int i = 0; i < n * m; i++) e[i].clear(); 22 for(int i = 1; i <= n; i++) 23 for(int j = 1; j <= m; j++) 24 e[G[i][j]].push_back(pii(i, j)); 25 LL ans = 0; 26 for(int i = 0; i < n * m; i++) 27 { 28 if(!e[i].size()) continue; 29 for(int j = 1; j <= m; j++) low[j] = 0; 30 int sz = e[i].size(); 31 for(int j = 0; j < sz; j++) 32 { 33 int x = e[i][j].first, y = e[i][j].second; 34 int st = !j || e[i][j-1].first != x ? 1 : e[i][j-1].second + 1; 35 int p1 = y, p2 = y; 36 for(int minv = x - low[y]; minv; minv--) 37 { 38 while(p1 > st && x - low[p1-1] >= minv) p1--; 39 while(p2 < m && x - low[p2+1] >= minv) p2++; 40 ans += (n - x + 1) * (y - p1 + 1) * (p2 - y + 1); 41 } 42 low[y] = x; 43 } 44 } 45 printf("%.9f ", 4.0 * ans / n / m / (n + 1) / (m + 1)); 46 } 47 return 0; 48 }
1009 TrickGCD
统计f[i]表示gcd为i倍数种数 再容斥一下
1 #include <iostream> 2 #include <cstdio> 3 #include <algorithm> 4 using namespace std; 5 typedef long long LL; 6 const LL mod = 1e9 + 7; 7 const int maxn = 1e5 + 10; 8 LL f[maxn]; // f[i] gcd为i倍数的方案数 9 int a[maxn]; 10 11 LL qpow(LL a, LL b) 12 { 13 LL ret = 1LL; 14 while(b) 15 { 16 if(b & 1) ret = ret * a % mod; 17 a = a * a % mod; 18 b >>= 1; 19 } 20 return ret; 21 } 22 23 int main(void) 24 { 25 int T; 26 scanf("%d", &T); 27 for(int kase = 1; kase <= T; kase++) 28 { 29 int n, ok = 1; 30 scanf("%d", &n); 31 for(int i = 1; i <= n; i++) 32 { 33 scanf("%d", a + i); 34 if(a[i] == 1) ok = 0; 35 } 36 if(!ok) {printf("Case #%d: 0 ", kase); continue;} 37 sort(a + 1, a + 1 + n); 38 for(int i = 2; i <= 100000; i++) 39 { 40 f[i] = 1; 41 if(a[1] < i) {f[i] = 0; continue;} 42 for(int j = i; j <= 100000; j += i) 43 { 44 int num = lower_bound(a + 1, a + 1 + n, j + i) - lower_bound(a + 1, a + 1 + n, j); 45 f[i] = f[i] * qpow(j / i, num) % mod; 46 } 47 } 48 LL ans = 0; 49 for(int i = 100000; i >= 2; i--) 50 { 51 for(int j = i + i; j <= 100000; j += i) f[i] = (f[i] - f[j] + mod) % mod; 52 ans = (ans + f[i]) % mod; 53 } 54 printf("Case #%d: %lld ", kase, ans); 55 } 56 return 0; 57 }
1010 String and String
1011 Regular polygon
暴力
1 #include <iostream> 2 #include <cstdio> 3 #include <set> 4 using namespace std; 5 typedef pair<int, int> pii; 6 int x[555], y[555]; 7 set<pii> S; 8 9 int main(void) 10 { 11 int n; 12 while(~scanf("%d", &n)) 13 { 14 for(int i = 1; i <= n; i++) scanf("%d %d", x + i, y + i); 15 S.clear(); 16 int ans = 0; 17 for(int i = 1; i <= n; i++) S.insert(pii(x[i], y[i])); 18 for(int i = 1; i <= n; i++) 19 { 20 for(int j = i + 1; j <= n; j++) 21 { 22 int dx = x[j] - x[i], dy = y[j] - y[i]; 23 if(S.find(pii(x[i] + dy, y[i] - dx)) != S.end() && S.find(pii(x[j] + dy, y[j] - dx)) != S.end()) ans++; 24 if(S.find(pii(x[i] - dy, y[i] + dx)) != S.end() && S.find(pii(x[j] - dy, y[j] + dx)) != S.end()) ans++; 25 } 26 S.erase(pii(x[i], y[i])); 27 } 28 printf("%d ", ans / 2); 29 } 30 return 0; 31 }