A - Intersection 
题意 
给出两条线段,求交集长度
题解 
暴力
代码 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 #include <bits/stdc++.h>  using  namespace  std;using  LL = long  long ;const  int  N = 2e5  + 5 , MOD = 998244353 , INF = 0x3f3f3f3f ;signed  main ()   {    cin.tie (nullptr )->sync_with_stdio (false );     int  l1, r1, l2, r2;     cin >> l1 >> r1 >> l2 >> r2;     vector< int  > a (101 )  ;     for  (int  i = l1; i <= r1; ++ i) {         a[i] = 1 ;     }     int  ans = 0 ;     for  (int  i = l2; i <= r2; ++ i) {         ans += a[i];     }     if  (ans) -- ans;     cout << ans << '\n' ;     return  0 ; } 
 
B - Tournament Result 
题意 
一个二维矩阵,$A_{i,j}$为W则$i$击败$j$,为L则$i$败给$j$,为D则$i$和$j$打成平局
求是否冲突
The table is said to be contradictory when some of the following holds:
There is a pair (i ,j ) such that Player i  beat Player j , but Player j  did not lose to Player i ; 
There is a pair (i ,j ) such that Player i  lost to Player j , but Player j  did not beat Player i ; 
There is a pair (i ,j ) such that Player i  drew with Player j , but Player j  did not draw with Player i . 
 
 
题解 
模拟
代码 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 #include <bits/stdc++.h>  using  namespace  std;using  LL = long  long ;const  int  N = 1005 , MOD = 998244353 , INF = 0x3f3f3f3f ;int  n;string s[N]; int  dis[N][N];signed  main ()   {    cin.tie (nullptr )->sync_with_stdio (false );     cin >> n;     for  (int  i = 0 ; i < n; ++ i) {         cin >> s[i];     }     bool  safe = true ;     for  (int  i = 0 ; i < n; ++ i) {         for  (int  j = i + 1 ; j < n; ++ j) {             if  (s[i][j] == 'D'  && s[j][i] != 'D' ) {                 safe = false ;             }             if  (s[i][j] == 'W'  && s[j][i] != 'L' ) {                 safe = false ;             }             if  (s[i][j] == 'L'  && s[j][i] != 'W' ) {                 safe = false ;             }         }     }     cout << (safe ? "correct"  : "incorrect" ) << '\n' ;     return  0 ; } 
 
C - NewFolder(1) 
题意 
给出n个字符串,要求以 $s_i+(\sum_{j=1}^{i-1}s_j==s[i])$ 的形式输出 n 个字符串
题解 
模拟
代码 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 #include <bits/stdc++.h>  using  namespace  std;using  LL = long  long ;const  int  N = 2e5  + 5 , MOD = 998244353 , INF = 0x3f3f3f3f ;int  n;string s[N]; signed  main ()   {    cin.tie (nullptr )->sync_with_stdio (false );     cin >> n;     string str;     for  (int  i = 1 ; i <= n; ++ i) {         cin >> s[i];     }     map< string, int  > cnt;     for  (int  i = 1 ; i <= n; ++ i) {         if  (!cnt[s[i]]) {             cout << s[i] << '\n' ;         } else  {             cout << s[i] + '('  + to_string (cnt[s[i]]) + ')'  << '\n' ;         }         ++ cnt[s[i]];     }     return  0 ; } 
 
D - Flipping and Bonus 
题意 
Takahashi会投掷$n$次硬币,若第$i$次硬币为正面,则他会获得$X_i$元的奖励,同时给出$m$个附加奖励,当他每次连续投掷正面的次数为$C_i$时他会额外获得$Y_i$元的奖励,求Takahashi能获得的最大钱数。
题解 
我们定义$dp_{i,j}$为投掷第$i$次硬币后,连续正面次数为$j$的最大收益
若第$i$次投掷的是正面
$dp_{i,j}=dp_{i-1,j-1}+X_i$
 
若第$i$次投掷的是反面,那么连续正面次数重置为0
$dp_{i,0}=\max(dp_{i,0},dp_{i-1,j})$
 
接下来考虑额外奖励
$dp_{i,C_j}=\max\left( dp_{i,C_j},dp_{i-1,C_j-1+Y_j+X_i} \right)$
 
 
代码 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 #include <bits/stdc++.h>  using  namespace  std;using  LL = long  long ;const  int  N = 5005 , MOD = 998244353 , INF = 0x3f3f3f3f ;int  n, m, x[N], c[N], y[N];LL dp[N][N]; signed  main ()   {    cin.tie (nullptr )->sync_with_stdio (false );     cin >> n >> m;     for  (int  i = 1 ; i <= n; ++ i) {         cin >> x[i];     }     for  (int  i = 1 ; i <= m; ++ i) {         cin >> c[i] >> y[i];     }     for  (int  i = 1 ; i <= n; ++ i) {         for  (int  j = 0 ; j <= i - 1 ; ++ j) {             dp[i][j + 1 ] = dp[i - 1 ][j] + x[i];             dp[i][0 ] = max (dp[i][0 ], dp[i - 1 ][j]);         }         for  (int  j = 1 ; j <= m; ++ j) {             if  (c[j] <= i) {                 dp[i][c[j]] = max (dp[i][c[j]], dp[i - 1 ][c[j] - 1 ] + y[j] + x[i]);             }         }     }     LL ans = 0 ;     for  (int  i = 1 ; i <= n; ++ i) {         for  (int  j = 0 ; j <= n; ++ j) {             ans = max (ans, dp[i][j]);         }     }     cout << ans << '\n' ;     return  0 ; } 
 
E - Many Operations 
题意 
我们有一个初值$X$,以及$n$个操作$op, A_i$
若$op=1$ ,则令 $X= X$ & $A_i$ 
若$op=2$ ,则令 $X=X|A_i$ 
若$op=3$ ,则令 $X=X\bigoplus A_i$ 
 
我们令初值$X$进行了前$i$次操作后的值为$Y_i$,输出$Y_i(1 \leq i \leq n)$
题解 
初一看,感觉是个很厉害的题,细想后发现可以对每一位分别考虑。
分别计算初始值每一位为$0$ 或 $1$,进行$i$次运算后的值,第$i$ 次的初始值为 $Y_{i-1}$ ,对 $Y_{i-1}$的每一位统计即可
代码 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 #include <bits/stdc++.h>  using  namespace  std;using  LL = long  long ;const  int  N = 2e5  + 5 , MOD = 998244353 , INF = 0x3f3f3f3f ;int  n, C;signed  main ()   {    cin.tie (nullptr )->sync_with_stdio (false );     cin >> n >> C;     int  X = (1  << 30 ) - 1 , Y = 0 ;     for  (int  i = 1 ; i <= n; ++ i) {         int  op, x;         cin >> op >> x;         if  (op == 1 ) {             X &= x;             Y &= x;         } else  if  (op == 2 ) {             X |= x;             Y |= x;         } else  {             X ^= x;             Y ^= x;         }         LL ans = 0 ;         for  (int  j = 0 ; j < 30 ; ++ j) {             if  (C >> j & 1 ) {                 ans |= (X >> j & 1 ) << j;             } else  {                 ans |= (Y >> j & 1 ) << j;             }         }         cout << (C = ans) << '\n' ;     }     return  0 ; } 
 
F - Sorting Color Balls 
题意 
给定$n$个元素,每个元素有一个值和一个颜色,每次操作可以交换相邻的两个元素,若这两个元素颜色不同,则需要消耗一点$cost$,询问通过操作将这$n$个元素按非递减排列所需要的最小$cost$
题解 
首先不考虑颜色,其代价显然是数组的逆序对个数
现在加上颜色的限制,其代价就是总的逆序对个数减去同种颜色之间逆序对的个数,维护这个即可。
这里我用了非树状数组的方法来求同种颜色之间逆序对的个数,从后往前遍历,我们每次把$X_i$顺序插入$C_i$对应的数组,询问时我们查询当前的$X_i$位于$C_i$对应的数组第几个即可,$j>i$且$X_j<X_i$符合逆序对定义嘛
代码 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 #include <bits/stdc++.h>  using  namespace  std;using  LL = long  long ;const  int  N = 3e5  + 5 , MOD = 998244353 , INF = 0x3f3f3f3f ;int  n, c[N], x[N];vector< int  > col[N]; struct  FenWick  {    int  n;     vector< int  > c;     FenWick (int  n) : n (n), c (n + 1 ) {}     void  add (int  i, int  d)   {         for  (; i <= n; i += i & -i) {             c[i] += d;         }     }     void  add (int  l, int  r, int  d)   {         add (l, d);         add (r + 1 , -d);     }     int  get (int  i)   {         int  sum = 0 ;         for  (; i; i -= i & -i) {             sum += c[i];         }         return  sum;     }     int  get (int  l, int  r)   {          return  get (r) - get (l - 1 );     } }; signed  main ()   {    cin.tie (nullptr )->sync_with_stdio (false );     cin >> n;     for  (int  i = 1 ; i <= n; ++ i) {         cin >> c[i];     }     for  (int  i = 1 ; i <= n; ++ i) {         cin >> x[i];     }     LL ans = 0 ;     FenWick k (n)  ;     for  (int  i = n; i >= 1 ; -- i) {         ans += k.get (x[i] - 1 );         k.add (x[i], 1 );         ans -= upper_bound (col[c[i]].begin (), col[c[i]].end (), x[i] - 1 ) - col[c[i]].begin ();         col[c[i]].insert (upper_bound (begin (col[c[i]]), end (col[c[i]]), x[i]), x[i]);     }     cout << ans << '\n' ;     return  0 ; }