AtCoder Grand Contest 023

A - Zero-Sum Ranges

暴力

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 typedef long long LL;
 4 map<LL, LL> cnt;
 5 const int maxn = 2e5 + 10;
 6 LL a[maxn], sum[maxn];
 7 
 8 int main(){
 9     int N;
10     LL ans = 0;
11     scanf("%d", &N);
12     cnt[0]++;
13     for(int i = 1; i <= N; ++i){
14         scanf("%lld", a + i), sum[i] = sum[i-1] + a[i];
15         ans += cnt[sum[i]];
16         cnt[sum[i]]++;
17     }
18     printf("%lld\n", ans);
19     return 0;
20 }
Aguin

 

B - Find Symmetries

暴力

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 int G[666][666], len[666][666];
 4 char s[666];
 5 
 6 int main(){
 7     int N;
 8     scanf("%d", &N);
 9     for(int i = 1; i <= N; ++i){
10         scanf("%s", s + 1);
11         for(int j = 1; j <= N; ++j) G[i][j] = s[j] - 'a' + 1;
12     }
13     for(int i = 1; i <= N; ++i){
14         for(int j = 1; j <= N; ++j){
15             G[i+N][j] = G[i][j+N] = G[i+N][j+N] = G[i][j];
16         }
17     }
18     for(int i = 1; i <= N + N; ++i){
19         for(int j = 1; j <= N + N; ++j){
20             int l = 1;
21             while(i + l <= N + N && j + l <= N + N && G[i][j+l] == G[i+l][j]) l++;
22             len[i][j] = l;
23         }
24     }
25     int ans = 0;
26     for(int i = 1; i <= N; ++i){
27         for(int j = 1; j <= N; ++j){
28             int ok = 1;
29             for(int k = 0; k < N; ++k){
30                 if(len[i+k][j+k] < N - k) {ok = 0; break;}
31             }
32             ans += ok;
33         }
34     }
35     printf("%d\n", ans);
36     return 0;
37 }
Aguin

 

C - Painting Machines

容斥

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 typedef long long LL;
 4 const LL mod = 1e9 + 7;
 5 const int maxn = 1e6 + 10;
 6 LL fac[maxn], inv_fac[maxn], num[maxn];
 7 
 8 LL qpow(LL a, LL b) {
 9     LL ret = 1LL;
10     while (b) {
11         if (b & 1) ret = ret * a % mod;
12         a = a * a % mod;
13         b >>= 1;
14     }
15     return ret;
16 }
17 
18 LL inv(LL x) {
19     return qpow(x, mod - 2);
20 }
21 
22 LL C(int n, int m) {
23     return fac[n] * inv_fac[m] % mod * inv_fac[n - m] % mod;
24 }
25 
26 int main() {
27     int N;
28     scanf("%d", &N);
29     if(N == 2) {puts("1"); return 0;}
30     fac[0] = 1;
31     for (int i = 1; i <= N; ++i) fac[i] = fac[i - 1] * i % mod;
32     inv_fac[N] = inv(fac[N]);
33     for (int i = N - 1; i >= 0; --i) inv_fac[i] = inv_fac[i + 1] * (i + 1) % mod;
34     for (int i = (N + 1) / 2; i <= N - 1; ++i)
35         num[i] = C(i - 1, N - 1 - i) * fac[i] % mod * fac[N - 1 - i] % mod;
36     LL ans = 0;
37     for (int i = N - 1; i >= (N + 1) / 2; i--) {
38         num[i] = (num[i] - num[i - 1] + mod) % mod;
39         ans = (ans + num[i] * i) % mod;
40     }
41     printf("%lld\n", ans);
42     return 0;
43 }
Aguin

 

D - Go Home

两边往中间考虑

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 typedef long long LL;
 4 const int maxn = 1e5 + 10;
 5 int X[maxn];
 6 LL P[maxn];
 7 
 8 int main() {
 9     int N, S;
10     scanf("%d %d", &N, &S);
11     for(int i = 1; i <= N; ++i) scanf("%d %lld", X + i, P + i);
12     int p1 = 1, p2 = N, d = 0;
13     LL ans = 0;
14     while(1){
15         if(X[p1] >= S) {ans += X[p2] - S; break;}
16         if(X[p2] <= S) {ans += S - X[p1]; break;}
17         if(P[p1] < P[p2]) {
18             if(d != -1) ans += X[p2] - X[p1], d = -1;
19             P[p2] += P[p1], p1++;
20         }
21         else {
22             if(d != 1) ans += X[p2] - X[p1], d = 1;
23             P[p1] += P[p2], p2--;
24         }
25     }
26     printf("%lld\n", ans);
27     return 0;
28 }
Aguin

 

E - Inversions

对于i和j位置根据大小关系分三类讨论

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 typedef long long LL;
 4 const LL mod = 1e9 + 7;
 5 const int maxn = 2e5 + 10;
 6 int A[maxn], cnt[maxn], st[maxn], ed[maxn];
 7 LL D[maxn], C[maxn];
 8 
 9 LL qpow(LL a, LL b) {
10     LL ret = 1LL;
11     while (b) {
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     return qpow(x, mod - 2);
21 }
22 
23 LL c[2][maxn];
24 int lowbit(int s) {
25     return s & (-s);
26 }
27 void modify(int o, int i, LL x) {
28     while (i < maxn) c[o][i] = (c[o][i] + x) % mod, i += lowbit(i);
29     return;
30 }
31 LL query(int o, int i) {
32     LL ret = 0;
33     while (i > 0) ret = (ret + c[o][i]) % mod, i -= lowbit(i);
34     return ret;
35 }
36 
37 int main() {
38     int N;
39     scanf("%d", &N);
40     for (int i = 1; i <= N; ++i) scanf("%d", A + i), cnt[A[i]]++;
41     for (int i = N; i >= 1; --i) cnt[i] += cnt[i + 1];
42     LL S = 1;
43     for (int i = 1; i <= N; ++i) {
44         cnt[i] -= N - i;
45         if (cnt[i] <= 0) S = 0;
46         else S = S * cnt[i] % mod;
47     }
48     if (S == 0) {
49         puts("0");
50         return 0;
51     }
52     for (int i = N; i >= 1; --i) {
53         if (i == N || cnt[i + 1] == 1 || cnt[i] == 1) st[i] = ed[i] = i;
54         else st[i] = st[i + 1], ed[st[i]] = i;
55     }
56     for(int i = 1; i <= N; ++i){
57         LL pre;
58         if(ed[st[i]] == i) pre = 1;
59         else pre = D[i-1];
60         D[i] = pre * (cnt[i] - 1) % mod * inv(cnt[i]) % mod;
61     }
62     LL ans = 0;
63     for (int j = 1; j <= N; ++j) {
64         ans = (ans + C[A[j]]) % mod;
65         C[A[j]]++;
66         if(!D[A[j]]) continue;
67         LL tmp = (query(0, A[j] - 1) - query(0, ed[st[A[j]]] - 2) + mod) % mod;
68         ans = (ans + tmp * D[A[j]]) % mod;
69         modify(0, A[j], inv(D[A[j]]));
70     }
71     memset(c[0], 0, sizeof(c[0]));
72     LL sum = 0;
73     for (int j = N; j >= 1; --j) {
74         sum = (sum + query(1, A[j] - 1)) % mod;
75         modify(1, A[j], 1);
76         if(!D[A[j]]) continue;
77         LL tmp = (query(0, A[j] - 1) - query(0, ed[st[A[j]]] - 2) + mod) % mod;
78         ans = (ans - tmp * D[A[j]] % mod + mod) % mod;
79         modify(0, A[j], inv(D[A[j]]));
80     }
81     ans = (ans * inv(2) % mod + sum) * S % mod;
82     printf("%lld\n", ans);
83     return 0;
84 }
Aguin

 

F - 01 on Tree

维护每个点0/1的比值每次贪心把比值最大的往父亲合并

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 typedef long long LL;
 4 const int maxn = 2e5 + 10;
 5 int P[maxn], V[maxn], tl[maxn], nxt[maxn];
 6 int c0[maxn], c1[maxn];
 7 
 8 struct node {
 9     int id;
10     node(int id = -1) : id(id) {}
11     friend bool operator<(node A, node B) {
12         if ((LL) c0[A.id] * c1[B.id] != (LL) c0[B.id] * c1[A.id])
13             return (LL) c0[A.id] * c1[B.id] > (LL) c0[B.id] * c1[A.id];
14         return A.id < B.id;
15     }
16 };
17 set<node> S;
18 
19 int fa[maxn];
20 int Find(int x){
21     return fa[x] == x ? x : fa[x] = Find(fa[x]);
22 }
23 
24 int main() {
25     int N;
26     scanf("%d", &N);
27     for (int i = 2; i <= N; ++i) scanf("%d", P + i);
28     for (int i = 1; i <= N; ++i) {
29         fa[i] = tl[i] = i;
30         scanf("%d", V + i);
31         if (V[i] == 0) c0[i] = 1;
32         else c1[i] = 1;
33         if(i != 1) S.insert(node(i));
34     }
35     for (int i = 1; i < N; ++i) {
36         node now = *S.begin();
37         S.erase(S.begin());
38         int x = now.id, y = Find(P[x]);
39         nxt[tl[y]] = x, tl[y] = tl[x], fa[x] = y;
40         if(y != 1) S.erase(node(y));
41         c1[y] += c1[x], c0[y] += c0[x];
42         if(y != 1) S.insert(node(y));
43     }
44     LL ans = 0;
45     int p = 1, num = V[1];
46     for (int i = 1; i < N; ++i) {
47         p = nxt[p];
48         if (V[p] == 0) ans += num;
49         else num++;
50     }
51     printf("%lld\n", ans);
52     return 0;
53 }
Aguin

 

posted @ 2018-04-29 19:34  Aguin  阅读(173)  评论(0编辑  收藏  举报