2017 Multi-University Training Contest - Team 2

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\n", kase, i - x + 1, j - y + 1);
55                     ok = 1; break;
56                 }
57             }
58             if(ok) break;
59         }
60     }
61     return 0;
62 }
Aguin

 

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\n", sum % mod);
29     }
30     return 0;
31 }
Aguin

 

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 }
Aguin

 

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\n", ans);
49     }
50     return 0;
51 }
Aguin

据说是可以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\n", ans);
38     }
39     return 0;
40 }
Aguin

 

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\n", 4.0 * ans / n / m / (n + 1) / (m + 1));
46     }
47     return 0;
48 }
Aguin

 

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\n", 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\n", kase, ans);
55     }
56     return 0;
57 }
Aguin

 

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\n", ans / 2);
29     }
30     return 0;
31 }
Aguin
posted @ 2017-07-29 15:55  Aguin  阅读(234)  评论(0编辑  收藏  举报