제출 #298767

#제출 시각아이디문제언어결과실행 시간메모리
298767Pro_ktmrMonochrome Points (JOI20_monochrome)C++14
35 / 100
2062 ms262540 KiB
#pragma GCC target ("avx2") #pragma GCC optimize ("unroll-loops") #pragma GCC optimize ("O3") #include "bits/stdc++.h" #include <unordered_set> #include <unordered_map> #include <random> using namespace std; typedef long long ll; const ll MOD = 1'000'000'007LL; /*998'244'353LL;*/ #define pb push_back #define mp make_pair #define all(x) (x).begin(), (x).end() #define rep(i, n) for(int (i)=0; (i)<(n); (i)++) const int dx[4]={ 1,0,-1,0 }; const int dy[4]={ 0,1,0,-1 }; template<typename T> struct TreapSet{ private: struct Node{ T x; // value int p; // priority Node* par; // parent Node* chi[2]; // children int s; // size of subtree T m; // minimum value of subtree Node(T _x, std::mt19937& mt){ x = _x; p = mt(); par = NULL; chi[0] = NULL; chi[1] = NULL; s = 1; m = _x; } bool operator==(const Node& u){ return x == u.x; } bool operator<(const Node& u){ return x < u.x; } }; int N; Node* root; std::mt19937 mt; Node* find(T _x){ Node* u = root; while(u != NULL && u->x != _x){ if(u->x > _x) u = u->chi[0]; else u = u->chi[1]; } return u; } void update(Node* u){ u->s = (u->chi[0] != NULL ? u->chi[0]->s : 0) + (u->chi[1] != NULL ? u->chi[1]->s : 0) + 1; u->m = u->x; if(u->chi[0] != NULL && u->chi[0]->m < u->m) u->m = u->chi[0]->m; if(u->chi[1] != NULL && u->chi[1]->m < u->m) u->m = u->chi[1]->m; } void rotateRight(Node* u){ Node* p = u->par; u->par = p->par; if(p->par != NULL){ if(p->par->chi[0] == p) p->par->chi[0] = u; else p->par->chi[1] = u; } p->par = u; p->chi[0] = u->chi[1]; if(u->chi[1] != NULL) u->chi[1]->par = p; u->chi[1] = p; update(p); update(u); } void rotateLeft(Node* u){ Node* p = u->par; u->par = p->par; if(p->par != NULL){ if(p->par->chi[0] == p) p->par->chi[0] = u; else p->par->chi[1] = u; } p->par = u; p->chi[1] = u->chi[0]; if(u->chi[0] != NULL) u->chi[0]->par = p; u->chi[0] = p; update(p); update(u); } void bubbleUp(Node* u){ while(u->par != NULL && u->par->p > u->p){ if(u->par->chi[0] == u) rotateRight(u); else rotateLeft(u); } if(u->par == NULL) root = u; } public: TreapSet(){ N = 0; root = NULL; std::mt19937 mt2(869120); mt = mt2; } void add(T _x){ Node* u = new Node(_x, mt); if(N == 0){ root = u; } else{ Node* p = root; Node* v = root; while(v != NULL){ p = v; p->s++; if(p->m > _x) p->m = _x; if(v->x > _x) v = v->chi[0]; else v = v->chi[1]; } if(p->x > _x){ p->chi[0] = u; u->par = p; } else{ p->chi[1] = u; u->par = p; } bubbleUp(u); } N++; } int lower_bound(T _x){ Node* u = root; bool seted = false; T ret; while(u != NULL){ if(u->x >= _x && (!seted || u->x < ret)){ ret = u->x; seted = true; } if(u->chi[0] == NULL) u = u->chi[1]; else if(u->chi[1] == NULL) u = u->chi[0]; else if(u->chi[1]->m <= _x) u = u->chi[1]; else{ if(!seted || ret > u->chi[1]->m){ ret = u->chi[1]->m; seted = true; } u = u->chi[0]; } } if(!seted) return N; return index(ret); } int index(T _x){ Node* u = root; int ret = 0; while(u != NULL && u->x != _x){ if(u->x > _x) u = u->chi[0]; else{ ret += (u->chi[0] != NULL ? u->chi[0]->s : 0) + 1; u = u->chi[1]; } } if(u == NULL) return -1; if(u->chi[0] != NULL) ret += u->chi[0]->s; return ret; } }; void rotate(vector<pair<int,int>> &v, int idx){ vector<pair<int,int>> ret; for(int i=idx; i<v.size(); i++) ret.pb(v[idx]); rep(i, idx) ret.pb(v[i]); v = ret; } void merge(vector<pair<int,int>> &a, vector<pair<int,int>> &b){ int N = a.size() + b.size(); int i = a.size()-1; int j = b.size()-1; a.resize(N); for(int k=N-1; k>=0; k--){ if(i == -1){ a[k] = b[j]; j--; } else if(j == -1){ a[k] = a[i]; i--; } else if(a[i] > b[j]){ a[k] = a[i]; i--; } else{ a[k] = b[j]; j--; } } } int N; char S[400001]; vector<int> B, W; ll memo[200000]; ll solve(int i){ if(memo[i] != -1) return memo[i]; vector<pair<int,int>> v, v2; rep(j, N){ int a = B[j]; int b = W[(i+j)%N]; if(a > b){ v.pb({a, b}); } else{ v2.pb({b, a}); } } rep(j, (int)v2.size()-1){ if(v2[j] > v2[j+1]){ rotate(v2, j+1); break; } } merge(v, v2); TreapSet<int> st; ll tmp = 0; for(int j=N-1; j>=0; j--){ tmp += st.lower_bound(v[j].first) - st.lower_bound(v[j].second+1); st.add(v[j].second); } return memo[i] = tmp; } signed main(){ scanf("%d", &N); scanf("%s", S); rep(i, 2*N){ if(S[i] == 'B') B.pb(i); if(S[i] == 'W') W.pb(i); } memset(memo, -1, sizeof(memo)); ll ans = 0; int v = (N+1) / 2; int n = 0; while(v > 0){ ll a1 = solve(n); ll a2 = solve((n+1)%N); ans = max({ans,a1,a2}); if(a1 >= a2) n = (n-v+N) % N; else n = (n+v) % N; if(v == 1) break; v = (v+1) / 2; } printf("%lld\n", ans); }

컴파일 시 표준 에러 (stderr) 메시지

monochrome.cpp: In function 'void rotate(std::vector<std::pair<int, int> >&, int)':
monochrome.cpp:173:21: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<std::pair<int, int> >::size_type' {aka 'long unsigned int'} [-Wsign-compare]
  173 |     for(int i=idx; i<v.size(); i++) ret.pb(v[idx]);
      |                    ~^~~~~~~~~
monochrome.cpp:14:27: warning: unnecessary parentheses in declaration of 'i' [-Wparentheses]
   14 | #define rep(i, n) for(int (i)=0; (i)<(n); (i)++)
      |                           ^
monochrome.cpp:174:5: note: in expansion of macro 'rep'
  174 |     rep(i, idx) ret.pb(v[i]);
      |     ^~~
monochrome.cpp: In function 'll solve(int)':
monochrome.cpp:14:27: warning: unnecessary parentheses in declaration of 'j' [-Wparentheses]
   14 | #define rep(i, n) for(int (i)=0; (i)<(n); (i)++)
      |                           ^
monochrome.cpp:210:5: note: in expansion of macro 'rep'
  210 |     rep(j, N){
      |     ^~~
monochrome.cpp:14:27: warning: unnecessary parentheses in declaration of 'j' [-Wparentheses]
   14 | #define rep(i, n) for(int (i)=0; (i)<(n); (i)++)
      |                           ^
monochrome.cpp:220:5: note: in expansion of macro 'rep'
  220 |     rep(j, (int)v2.size()-1){
      |     ^~~
monochrome.cpp: In function 'int main()':
monochrome.cpp:14:27: warning: unnecessary parentheses in declaration of 'i' [-Wparentheses]
   14 | #define rep(i, n) for(int (i)=0; (i)<(n); (i)++)
      |                           ^
monochrome.cpp:240:5: note: in expansion of macro 'rep'
  240 |     rep(i, 2*N){
      |     ^~~
monochrome.cpp:238:10: warning: ignoring return value of 'int scanf(const char*, ...)', declared with attribute warn_unused_result [-Wunused-result]
  238 |     scanf("%d", &N);
      |     ~~~~~^~~~~~~~~~
monochrome.cpp:239:10: warning: ignoring return value of 'int scanf(const char*, ...)', declared with attribute warn_unused_result [-Wunused-result]
  239 |     scanf("%s", S);
      |     ~~~~~^~~~~~~~~
monochrome.cpp: In function 'll solve(int)':
monochrome.cpp:145:27: warning: 'ret' may be used uninitialized in this function [-Wmaybe-uninitialized]
  145 |                 if(!seted || ret > u->chi[1]->m){
      |                    ~~~~~~~^~~~~~~~~~~~~~~~~~~~~
monochrome.cpp:135:11: note: 'ret' was declared here
  135 |         T ret;
      |           ^~~
monochrome.cpp:145:27: warning: 'ret' may be used uninitialized in this function [-Wmaybe-uninitialized]
  145 |                 if(!seted || ret > u->chi[1]->m){
      |                    ~~~~~~~^~~~~~~~~~~~~~~~~~~~~
monochrome.cpp:135:11: note: 'ret' was declared here
  135 |         T ret;
      |           ^~~
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...