2018 Multi-University Training Contest 2 Solution

A - Absolute

留坑。

B - Counting Permutations

留坑。

C - Cover

留坑。

D - Game

puts("Yes")

 1 #include <bits/stdc++.h>
 2 
 3 using namespace std;
 4 
 5 int n;
 6 
 7 int main()
 8 {
 9     while (scanf("%d", &n) != EOF)
10     {
11         puts("Yes");
12     }
13     return 0;
14 }
View Code

E - Hack It

留坑。

F - Matrix

留坑。

G - Naive Operations

题意:给出$b[]$数组,里面是$1-n$ 的全排列,两种操作,一个区间+1,一个是区间求$\sum_{i = l} ^ {i = r} \lfloor \frac{a_i}{b_i} \rfloor$

思路:维护一个Min 表示这个区间内需要的最少的进位,如果有进位,就更新到底,如果没有进位就区间更新

  1 #include <bits/stdc++.h>
  2 
  3 using namespace std;
  4 
  5 #define N 100010
  6 #define ll long long
  7 
  8 ll arr[N];
  9 
 10 struct node
 11 {
 12     int l, r;
 13     ll Min, lazy, sum, v;
 14     inline node() {}
 15     inline node(int _l, int _r)
 16     {
 17         l = _l; r = _r;
 18         Min = 0, lazy = 0, sum = 0, v = 0;
 19     }
 20 }tree[N << 2];
 21 
 22 inline void pushup(int id)
 23 {
 24     tree[id].Min = min(tree[id << 1].Min, tree[id << 1 | 1].Min);
 25     tree[id].sum = tree[id << 1].sum + tree[id << 1 | 1].sum;
 26 }
 27 
 28 inline void pushdown(int id)
 29 {
 30     if(tree[id].l >= tree[id].r) return;
 31     if(tree[id].lazy)
 32     {
 33         tree[id << 1].lazy += tree[id].lazy;
 34         tree[id << 1 | 1].lazy += tree[id].lazy;
 35         tree[id << 1].Min -= tree[id].lazy;
 36         tree[id << 1 | 1].Min -= tree[id].lazy;
 37         tree[id].lazy = 0;
 38     }
 39 }
 40 
 41 inline void build(int id, int l, int r)
 42 {
 43     tree[id] = node(l, r);
 44     if (l == r)
 45     {
 46         tree[id].v = arr[l];
 47         tree[id].Min = arr[l];
 48         return;
 49     }
 50     int mid = (l + r) >> 1;
 51     build(id << 1, l, mid);
 52     build(id << 1 | 1, mid + 1, r);
 53     pushup(id);
 54 }
 55 
 56 inline void update(int id, int l, int r)
 57 {
 58     if (tree[id].l == l && tree[id].r == r && tree[id].Min > 1)
 59     {
 60         tree[id].lazy++;
 61         tree[id].Min--;
 62         return ;
 63     }
 64     if(tree[id].l == tree[id].r && tree[id].Min == 1)
 65     {
 66         tree[id].Min = tree[id].v;
 67         tree[id].sum++;
 68         return ;
 69     }
 70     pushdown(id);
 71     int mid = (tree[id].l + tree[id].r) >> 1;
 72     if (r <= mid) update(id << 1, l, r);
 73     else if (l > mid) update(id << 1 | 1, l, r);
 74     else 
 75     {
 76         update(id << 1, l, mid);
 77         update(id << 1 | 1, mid + 1, r);
 78     }
 79     pushup(id);
 80 }
 81 
 82 ll anssum;
 83 
 84 inline void query(int id, int l, int r)
 85 {
 86     if (tree[id].l >= l && tree[id].r <= r)
 87     {
 88         anssum += tree[id].sum;
 89         return;
 90     }
 91     pushdown(id);
 92     int mid = (tree[id].l + tree[id].r) >> 1;
 93     if (l <= mid) query(id << 1, l, r);
 94     if (r > mid) query(id << 1 | 1, l, r);
 95     pushup(id);
 96 }
 97 
 98 int n, m;
 99 char str[100];
100 int l, r;
101 
102 int main()
103 {
104     while(~scanf("%d %d", &n, &m))
105     {
106         for(int i = 1; i <= n; ++i) scanf("%lld", arr + i);
107         build(1, 1, n);
108         for(int i = 1; i <= m; ++i)
109         {
110             scanf("%s", str);
111             if(str[0] == 'a')
112             {
113                 scanf("%d %d", &l, &r);
114                 update(1, l, r);
115             }    
116             else
117             {
118                 scanf("%d %d", &l, &r);
119                 anssum = 0;
120                 query(1, l, r);
121                 printf("%lld\n", anssum);
122             }
123         }
124     }
125     return 0;
126 }
View Code

H - Odd Shops

留坑。

I - Segment

留坑。

J - Swaps and Inversions

水。逆序对的意义就是每次只能交换相邻两个,最少的交换次数

 1 #include <bits/stdc++.h>
 2 
 3 using namespace std;
 4 
 5 #define ll long long
 6 #define N 100010
 7 
 8 int n, m; ll x, y;
 9 int arr[N], brr[N];
10 int a[N];
11 
12 inline void Init()
13 {
14     for (int i = 1; i <= n; ++i) brr[i] = arr[i];
15     sort(brr + 1, brr + 1 + n);
16     m = unique(brr + 1, brr + 1 + n) - brr - 1;
17 }
18 
19 inline int Get(int x)
20 {
21     return lower_bound(brr + 1, brr + 1 + m, x) - brr;
22 }
23 
24 inline int lowbit(int x)
25 {
26     return x & (-x);
27 }
28 
29 inline void update(int x, int val)
30 {
31     for (int i = x; i <= n; i += lowbit(i))
32         a[i] += val;
33 }
34 
35 inline int query(int x)
36 {
37     int res = 0;
38     for (int i = x; i > 0; i -= lowbit(i))
39         res += a[i];
40     return res;
41 }
42 
43 int main()
44 {
45     while (scanf("%d%lld%lld", &n, &x, &y) != EOF)
46     {
47         for (int i = 1; i <= n; ++i) scanf("%d", arr + i);
48         Init(); memset(a, 0, sizeof a);
49         for (int i = 1; i <= n; ++i) arr[i] = Get(arr[i]);
50         ll ans = 0;
51         for (int i = 1; i <= n; ++i)
52         {
53         //    ans += i - 1 - query(arr[i] - 1);
54         //    printf("%d %d\n", arr[i], query(arr[i] - 1));
55             update(arr[i], 1);
56             ans += i - query(arr[i]);
57         //    cout << arr[i] << " " << query(arr[i]) << endl;
58         }
59         printf("%lld\n", min(ans * x, ans * y));
60     }
61     return 0;
62 }
View Code

猜你喜欢

转载自www.cnblogs.com/Dup4/p/9566093.html