1. 程式人生 > >AtCoder Grand Contest 015 題解

AtCoder Grand Contest 015 題解

pan gin ken -- 出現 style 地方 連通塊 發現

A - A+...+B Problem

可以取到的值一定是一段區間。所以答案即為max-min+1

 1 //waz
 2 #include <bits/stdc++.h>
 3  
 4 using namespace std;
 5  
 6 #define mp make_pair
 7 #define pb push_back
 8 #define fi first
 9 #define se second
10 #define ALL(x) (x).begin(), (x).end()
11 #define SZ(x) ((int)((x).size()))
12  
13 typedef pair<int
, int> PII; 14 typedef vector<int> VI; 15 typedef long long int64; 16 typedef unsigned int uint; 17 typedef unsigned long long uint64; 18 19 #define gi(x) ((x) = F()) 20 #define gii(x, y) (gi(x), gi(y)) 21 #define giii(x, y, z) (gii(x, y), gi(z)) 22 23 int F() 24 { 25 char ch; 26 int
x, a; 27 while (ch = getchar(), (ch < 0 || ch > 9) && ch != -); 28 if (ch == -) ch = getchar(), a = -1; 29 else a = 1; 30 x = ch - 0; 31 while (ch = getchar(), ch >= 0 && ch <= 9) 32 x = (x << 1) + (x << 3) + ch - 0; 33 return
a * x; 34 } 35 36 int N, A, B; 37 38 int main() 39 { 40 giii(N, A, B); 41 B -= A; 42 int64 v = 1LL * (N - 1) * B - B + 1; 43 printf("%lld\n", v > 0 ? v : 0LL); 44 }

B - Evilator

首先如果方向不對就是2步,要不然就是一步,直接統計即可。

 1 //waz
 2 #include <bits/stdc++.h>
 3  
 4 using namespace std;
 5  
 6 #define mp make_pair
 7 #define pb push_back
 8 #define fi first
 9 #define se second
10 #define ALL(x) (x).begin(), (x).end()
11 #define SZ(x) ((int)((x).size()))
12  
13 typedef pair<int, int> PII;
14 typedef vector<int> VI;
15 typedef long long int64;
16 typedef unsigned int uint;
17 typedef unsigned long long uint64;
18  
19 #define gi(x) ((x) = F())
20 #define gii(x, y) (gi(x), gi(y))
21 #define giii(x, y, z) (gii(x, y), gi(z))
22  
23 int F()
24 {
25     char ch;
26     int x, a;
27     while (ch = getchar(), (ch < 0 || ch > 9) && ch != -);
28     if (ch == -) ch = getchar(), a = -1;
29     else a = 1;
30     x = ch - 0;
31     while (ch = getchar(), ch >= 0 && ch <= 9)
32         x = (x << 1) + (x << 3) + ch - 0;
33     return a * x;
34 }
35  
36 const int N = 1e5 + 10;
37  
38 char str[N];
39  
40 int n;
41  
42 long long ans;
43  
44 int main()
45 {
46     scanf("%s", str + 1);
47     n = strlen(str + 1);
48     for (int i = 1; i <= n; ++i)
49     {
50         if (str[i] == U)
51         {
52             ans += 2 * (i - 1);
53         }
54         else
55             ans += i - 1;
56     }
57     //cerr << ans << endl;
58     reverse(str + 1, str + n + 1);
59     //cnt = 0;
60     for (int i = 1; i <= n; ++i)
61     {
62         if (str[i] == D)
63         {
64             ans += 2 * (i - 1);
65         }
66         else
67             ans += i - 1;
68     }
69     printf("%lld\n", ans);
70 }

C - Nuske vs Phantom Thnook

圖是一棵樹,樹的連通塊個數=點數-邊數,那麽直接前綴和求點數、邊數即可。

 1 //waz
 2 #include <bits/stdc++.h>
 3  
 4 using namespace std;
 5  
 6 #define mp make_pair
 7 #define pb push_back
 8 #define fi first
 9 #define se second
10 #define ALL(x) (x).begin(), (x).end()
11 #define SZ(x) ((int)((x).size()))
12  
13 typedef pair<int, int> PII;
14 typedef vector<int> VI;
15 typedef long long int64;
16 typedef unsigned int uint;
17 typedef unsigned long long uint64;
18  
19 #define gi(x) ((x) = F())
20 #define gii(x, y) (gi(x), gi(y))
21 #define giii(x, y, z) (gii(x, y), gi(z))
22  
23 int F()
24 {
25     char ch;
26     int x, a;
27     while (ch = getchar(), (ch < 0 || ch > 9) && ch != -);
28     if (ch == -) ch = getchar(), a = -1;
29     else a = 1;
30     x = ch - 0;
31     while (ch = getchar(), ch >= 0 && ch <= 9)
32         x = (x << 1) + (x << 3) + ch - 0;
33     return a * x;
34 }
35  
36 char str[2010][2010];
37  
38 int a[2010][2010], b[2010][2010], c[2010][2010];
39  
40 int n, m, q;
41  
42 int main()
43 {
44     giii(n, m, q);
45     for (int i = 1; i <= n; ++i) scanf("%s", str[i] + 1);
46     for (int i = 1; i <= n; ++i)
47     {
48         for (int j = 1; j <= m; ++j)
49             if (str[i][j] == 1) ++a[i][j];
50         for (int j = 1; j < m; ++j)
51             if (str[i][j] == 1 && str[i][j + 1] == 1) ++b[i][j];
52         if (i < n)
53             for (int j = 1; j <= m; ++j)
54                 if (str[i][j] == 1 && str[i + 1][j] == 1) ++c[i][j];
55     }
56     for (int i = 1; i <= n; ++i)
57         for (int j = 1; j <= m; ++j)
58         {
59             a[i][j] += a[i][j - 1] + a[i - 1][j] - a[i - 1][j - 1];
60             b[i][j] += b[i][j - 1] + b[i - 1][j] - b[i - 1][j - 1];
61             c[i][j] += c[i][j - 1] + c[i - 1][j] - c[i - 1][j - 1];
62         }
63     while (q--)
64     {
65         int x1, y1, x2, y2;
66         gii(x1, y1);
67         gii(x2, y2);
68         int A = a[x2][y2] + a[x1 - 1][y1 - 1] - a[x2][y1 - 1] - a[x1 - 1][y2];
69         //cerr << "A = " << a[x2][y2] << endl;
70         int B = b[x2][y2 - 1] + b[x1 - 1][y1 - 1] - b[x2][y1 - 1] - b[x1 - 1][y2 - 1];
71         int C = c[x2 - 1][y2] + c[x1 - 1][y1 - 1] - c[x2 - 1][y1 - 1] - c[x1 - 1][y2];
72         printf("%d\n", A - B - C);
73     }
74     return 0;
75 }

D - A or...or B Problem

我們考慮第一次出現不同位置的地方,令A和B最高位不同,然後分類討論即可。

 1 //waz
 2 #include <bits/stdc++.h>
 3  
 4 using namespace std;
 5  
 6 #define mp make_pair
 7 #define pb push_back
 8 #define fi first
 9 #define se second
10 #define ALL(x) (x).begin(), (x).end()
11 #define SZ(x) ((int)((x).size()))
12  
13 typedef pair<int, int> PII;
14 typedef vector<int> VI;
15 typedef long long int64;
16 typedef unsigned int uint;
17 typedef unsigned long long uint64;
18  
19 #define gi(x) ((x) = F())
20 #define gii(x, y) (gi(x), gi(y))
21 #define giii(x, y, z) (gii(x, y), gi(z))
22  
23 int F()
24 {
25     char ch;
26     int x, a;
27     while (ch = getchar(), (ch < 0 || ch > 9) && ch != -);
28     if (ch == -) ch = getchar(), a = -1;
29     else a = 1;
30     x = ch - 0;
31     while (ch = getchar(), ch >= 0 && ch <= 9)
32         x = (x << 1) + (x << 3) + ch - 0;
33     return a * x;
34 }
35  
36 int64 A, B; 
37  
38 int main()
39 {
40     scanf("%lld%lld", &A, &B);
41     int p = 60;
42     if (A == B)
43     {
44         puts("1");
45         return 0;
46     }
47     while (!((A ^ B) & (1LL << p))) --p;
48     int q = p - 1;
49     while ((~q) && !(B & (1LL << q))) --q;
50     int64 x = (1LL << p) - (A & ((1LL << p) - 1));
51     int64 yl = (1LL << p), yr = (1LL << p) + (1LL << (q + 1));
52     int64 zl = (1LL << p) + (A & ((1LL << p) - 1)), zr = 2 * (1LL << p);
53     int64 ans = x + yr - yl + zr - zl;
54     if (zl <= yr)
55         ans -= yr - zl;
56     printf("%lld\n", ans);
57     return 0;
58 }

E - Mr.Aoki Incubator

我們發現本質就是區間覆蓋問題,線段樹dp即可。

  1 //waz
  2 #include <bits/stdc++.h>
  3  
  4 using namespace std;
  5  
  6 #define mp make_pair
  7 #define pb push_back
  8 #define fi first
  9 #define se second
 10 #define ALL(x) (x).begin(), (x).end()
 11 #define SZ(x) ((int)((x).size()))
 12  
 13 typedef pair<int, int> PII;
 14 typedef vector<int> VI;
 15 typedef long long int64;
 16 typedef unsigned int uint;
 17 typedef unsigned long long uint64;
 18  
 19 #define gi(x) ((x) = F())
 20 #define gii(x, y) (gi(x), gi(y))
 21 #define giii(x, y, z) (gii(x, y), gi(z))
 22  
 23 int F()
 24 {
 25     char ch;
 26     int x, a;
 27     while (ch = getchar(), (ch < 0 || ch > 9) && ch != -);
 28     if (ch == -) ch = getchar(), a = -1;
 29     else a = 1;
 30     x = ch - 0;
 31     while (ch = getchar(), ch >= 0 && ch <= 9)
 32         x = (x << 1) + (x << 3) + ch - 0;
 33     return a * x;
 34 }
 35  
 36 const int mod = 1e9 + 7;
 37  
 38 const int N = 2e5 + 10;
 39  
 40 int n;
 41  
 42 PII t[N];
 43  
 44 int id[N];
 45  
 46 int L[N], R[N];
 47  
 48 VI q[N];
 49  
 50 bool comp(const int &i, const int &j)
 51 {
 52     return t[i].se < t[j].se;
 53 }
 54  
 55 int tr[N];
 56  
 57 void add(int x, int v)
 58 {
 59     ++x;
 60     for (; x < N; x += x & -x) (tr[x] += v) %= mod;
 61 }
 62  
 63 int sum(int x)
 64 {
 65     ++x;
 66     int v = 0;
 67     for (; x; x -= x & -x) (v += tr[x]) %= mod;
 68     return v;
 69 }
 70  
 71 int query(int l, int r)
 72 {
 73     return (sum(r) - sum(l - 1) + mod) % mod;
 74 }
 75  
 76 int main()
 77 {
 78     gi(n);
 79     for (int i = 1; i <= n; ++i)
 80         gii(t[i].se, t[i].fi), id[i] = i;
 81     sort(t + 1, t + n + 1);
 82     sort(id + 1, id + n + 1, comp);
 83     int mi = n, mx = 0;
 84     for (int i = n; i; --i)
 85     {
 86         mi = min(mi, id[i]);
 87         L[i] = mi;
 88     }
 89     for (int i = 1; i <= n; ++i)
 90     {
 91         mx = max(mx, id[i]);
 92         R[i] = mx;
 93         q[R[i]].pb(L[i]);
 94         //cerr << L[i] << ", " << R[i] << endl;
 95     }
 96     add(0, 1);
 97     for (int r = 1; r <= n; ++r)
 98         for (auto l : q[r])
 99             add(r, query(l - 1, r));
100     printf("%d\n", query(n, n));
101     return 0;
102 }

F - Kenus the Ancient Greek

只會最優解,目前還不會方案數

AtCoder Grand Contest 015 題解