welleyth

TeamsCode 2021. P. ABC (Hard Version)

Sep 7th, 2021 (edited)
679
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 4.46 KB | None | 0 0
  1. #include <bits/stdc++.h>
  2. #include <ext/pb_ds/assoc_container.hpp>
  3. #include <ext/pb_ds/tree_policy.hpp>
  4.  
  5. using namespace std;
  6. using namespace __gnu_pbds;
  7.  
  8. #define pb push_back
  9. #define int long long
  10. #define uint __int128
  11. #define mp make_pair
  12. #define left left_compile
  13. #define right right_compile
  14.  
  15. #pragma GCC optimize("O3")
  16. #pragma GCC optimize("unroll-loops")
  17.  
  18. const int INF = (int)1e18;
  19. const int md = (int)1e9 + 7;
  20. const int MAXN = (int)100;
  21. const int N = (int)2e5 + 111;
  22. //const int L = 20;
  23. const int debug = 0;
  24. const long double eps = 1e-7;
  25.  
  26. mt19937 rnd(chrono::steady_clock::now().time_since_epoch().count());
  27.  
  28. struct DSU{
  29.     int n;
  30.     vector<int> parent;
  31.     vector<int> sz;
  32.     vector<int> deep;
  33.     DSU(int nn){
  34.         n = nn;
  35.         parent.resize(n+1);
  36.         sz.resize(n+1,1);
  37.         deep.resize(n+1,1);
  38.         for(int i = 0; i <= n; i++)
  39.             parent[i] = i, sz[i] = 1, deep[i] = 1;
  40.     }
  41.     int find_parent(int x){
  42.         if(parent[x] == x)
  43.             return x;
  44.         return parent[x] = find_parent(parent[x]);
  45.     }
  46.     void union_sets(int a,int b){
  47.         a = find_parent(a);
  48.         b = find_parent(b);
  49.         if(a == b)
  50.             return;
  51.         if(deep[a] <= deep[b])
  52.             parent[a] = b, sz[b] += sz[a], deep[b] = max(deep[b],deep[a]+1);
  53.         else
  54.             parent[b] = a, sz[a] += sz[b], deep[a] = max(deep[a],deep[b]+1);
  55.     }
  56.     bool connected(int a,int b){
  57.         return find_parent(a) == find_parent(b);
  58.     }
  59. };
  60.  
  61. //typedef tree<
  62. //int,
  63. //null_type,
  64. //less_equal<int>,
  65. //rb_tree_tag,
  66. //tree_order_statistics_node_update>
  67. //ordered_set;
  68.  
  69. int bpow(int a,int b){
  70.     if(b == 0)
  71.         return 1ll;
  72.     if(b % 2 == 0){
  73.         int t = bpow(a,b/2) % md;
  74.         return (t * t) % md;
  75.     }
  76.     return (a * bpow(a,b-1)) % md;
  77. }
  78.  
  79. int inv(int a){ /// return 1/a by PRIME modulo md
  80.     return bpow(a,md-2);
  81. }
  82.  
  83. //void myerase(ordered_set& st, int t){
  84. //    int r = st.order_of_key(t);
  85. //    ordered_set::iterator it = st.find_by_order(r);
  86. //    st.erase(it);
  87. //    return;
  88. //}
  89.  
  90. void init(){
  91.     return;
  92. }
  93.  
  94. void add(int& a,int b){
  95.     a = (a + b >= md ? a + b - md : a + b);
  96. }
  97.  
  98. void sub(int& a,int b){
  99.     a = (a < b ? a - b + md : a - b);
  100. }
  101.  
  102. int pref[3][N];
  103. int cnt[3];
  104.  
  105. int t[3][4*N];
  106. int dp[N];
  107.  
  108. void build(int v,int l,int r){
  109.     if(l == r){
  110.         t[0][v] = t[1][v] = t[2][v] = -INF;
  111.         return;
  112.     }
  113.     if(l > r)
  114.         return;
  115.     int m = (l + r) / 2;
  116.     build(v<<1,l,m);
  117.     build(v<<1|1,m+1,r);
  118.     t[0][v] = t[1][v] = t[2][v] = -INF;
  119.     return;
  120. }
  121.  
  122. int get(int v,int l,int r,int tl,int tr,int id){
  123.     if(l > r || tl > tr)
  124.         return -INF;
  125.     if(l == tl && r == tr)
  126.         return t[id][v];
  127.     int m = (l + r) / 2;
  128.     return max(get(v<<1,l,m,tl,min(tr,m),id),get(v<<1|1,m+1,r,max(tl,m+1),tr,id));
  129. }
  130.  
  131. void upd(int v,int l,int r,int pos,int nw,int id){
  132.     if(l == r){
  133.         t[id][v] = nw;
  134.         return;
  135.     }
  136.     if(l > r)
  137.         return;
  138.     int m = (l + r) / 2;
  139.     if(pos <= m)
  140.         upd(v<<1,l,m,pos,nw,id);
  141.     else
  142.         upd(v<<1|1,m+1,r,pos,nw,id);
  143.     t[id][v] = max(t[id][v<<1],t[id][v<<1|1]);
  144.     return;
  145. }
  146.  
  147. void solve_case(){
  148.     int n,k;
  149.     cin >> n >> k;
  150.  
  151.     string s;
  152.     cin >> s;
  153.  
  154.     for(int i = 1; i <= n; i++){
  155.         cnt[s[i-1]-'A']++;
  156.         for(int j = 0; j < 3; j++){
  157.             if(cnt[j] == max({cnt[0],cnt[1],cnt[2]})){
  158.                 pref[j][i] = 1;
  159.             }
  160.         }
  161.     }
  162.  
  163.     for(int i = 1; i < N; i++){
  164.         for(int j = 0; j < 3; j++){
  165.             pref[j][i] += pref[j][i-1];
  166.         }
  167.     }
  168.  
  169.     build(1,0,N-1);
  170.  
  171.     upd(1,0,N-1,0,0,0);
  172.     upd(1,0,N-1,0,0,1);
  173.     upd(1,0,N-1,0,0,2);
  174.  
  175.     int ans = 0;
  176.  
  177.     for(int i = k; i <= 2 * n; i++){
  178.         for(int j = 0; j < 3; j++){
  179.             int t = get(1,0,N-1,0,i-k,j) + pref[j][i];
  180.             dp[i] = max(dp[i],t);
  181.             ans = max(ans,dp[i]);
  182.         }
  183.         for(int j = 0; j < 3; j++){
  184.             upd(1,0,N-1,i,dp[i]-pref[j][i],j);
  185.         }
  186.     }
  187.  
  188.     cout << ans;
  189.  
  190.     return;
  191. }
  192.  
  193. signed main(){
  194.     ios_base::sync_with_stdio(false);cin.tie(0);cout.tie(0);
  195. //    freopen("internship.in","r",stdin);
  196. //    freopen("internship.out","w",stdout);
  197.  
  198. //    init();
  199.  
  200.     int tests = 1;
  201. //    cin >> tests;
  202.  
  203.     for(int _ = 1; _ <= tests; _++){
  204.         solve_case();
  205.     }
  206.  
  207.     return 0;
  208. }
  209.  
  210. /*
  211.  
  212. 4 <=> 100
  213. 7 <=> 111
  214. 3 <=> 011
  215.  
  216.  
  217. 0100
  218. 0111
  219.  
  220. 0100
  221. 0101
  222.  
  223. 111100111100
  224.  
  225. */
  226.  
Add Comment
Please, Sign In to add comment