Submission #414948

#TimeUsernameProblemLanguageResultExecution timeMemory
414948Pro_ktmrConstellation 3 (JOI20_constellation3)C++17
100 / 100
1325 ms81532 KiB
#pragma GCC target ("avx") #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 = (ll)(1e9+7); #define pb push_back #define mp make_pair #define all(x) (x).begin(), (x).end() #define rep(i, n) for(int (i)=0; (i)<(int)(n); (i)++) int dx[4]={ 1,0,-1,0 }; int dy[4]={ 0,1,0,-1 }; struct RMaxQ{ private: int N; vector<long long> node, lazy; long long DEFAULT; public: void init(int n, long long def=-9223372036854775807LL){ DEFAULT = def; N = 1; while(N < n) N = (N<<1); node.assign(2*N-1, DEFAULT); lazy.assign(2*N-1, 0); } void eval(int k, int l, int r){ node[k] += lazy[k]; if(r-l > 1){ lazy[(k<<1)+1] += lazy[k]; lazy[(k<<1)+2] += lazy[k]; } lazy[k] = 0LL; } void add(int a, long long x){ add(a, a+1, x); } void add(int a, int b, long long x, int k=0, int l=0, int r=-1){ if(a >= b) return; if(r == -1) r = N; eval(k, l, r); if(b <= l || r <= a) return; if(a <= l && r <= b){ lazy[k] += x; eval(k, l, r); } else{ add(a, b, x, (k<<1)+1, l, (l+r)>>1); add(a, b, x, (k<<1)+2, (l+r)>>1, r); node[k] = std::max(node[(k<<1)+1], node[(k<<1)+2]); } } long long max(int a, int b, int k=0, int l=0, int r=-1){ if(a >= b) return -9223372036854775807LL; if(r == -1) r = N; if(b <= l || r <= a) return -9223372036854775807LL; eval(k, l, r); if(a <= l && r <= b) return node[k]; return std::max(max(a, b, (k<<1)+1, l, (l+r)>>1), max(a, b, (k<<1)+2, (l+r)>>1, r)); } long long m; int find(int a, int b, int k=0, int l=0, int r=-1){ if(r == -1){ m = max(a, b); r = N; } if(r <= a || b <= l) return INT_MAX; if(r-l == 1){ if(node[k] == m) return l; else return INT_MAX; } if(a <= l && r <= b){ int valueL = max(a, b, (k<<1)+1, l, (l+r)/2); int valueR = max(a, b, (k<<1)+2, (l+r)/2, r); if(valueL == m) return find(a, b, (k<<1)+1, l, (l+r)>>1); if(valueR == m) return find(a, b, (k<<1)+2, (l+r)>>1, r); return INT_MAX; } return std::min(find(a, b, (k<<1)+1, l, (l+r)>>1), find(a, b, (k<<1)+2, (l+r)>>1, r)); } long long operator [](int a){ return max(a, a+1); } }; struct RMinQ{ private: int N; vector<long long> node, lazy; vector<bool> lazyFlg; long long DEFAULT; public: void init(int n, long long def=9223372036854775807LL){ DEFAULT = def; N = 1; while(N < n) N = (N<<1); node.assign(2*N-1, DEFAULT); lazy.assign(2*N-1, 0); lazyFlg.assign(2*N-1, false); } void eval(int k, int l, int r){ if(lazyFlg[k]){ node[k] = lazy[k]; if(r-l > 1){ lazy[(k<<1)+1] = lazy[k]; lazyFlg[(k<<1)+1] = true; lazy[(k<<1)+2] = lazy[k]; lazyFlg[(k<<1)+2] = true; } lazy[k] = 0LL; lazyFlg[k] = false; } } void update(int a, long long x){ update(a, a+1, x); } void update(int a, int b, long long x, int k=0, int l=0, int r=-1){ if(a >= b) return; if(r == -1) r = N; eval(k, l, r); if(b <= l || r <= a) return; if(a <= l && r <= b){ lazy[k] = x; lazyFlg[k] = true; eval(k, l, r); } else{ update(a, b, x, (k<<1)+1, l, (l+r)>>1); update(a, b, x, (k<<1)+2, (l+r)>>1, r); node[k] = std::min(node[(k<<1)+1], node[(k<<1)+2]); } } long long min(int a, int b, int k=0, int l=0, int r=-1){ if(a >= b) return 9223372036854775807LL; if(r == -1) r = N; if(b <= l || r <= a) return 9223372036854775807LL; eval(k, l, r); if(a <= l && r <= b) return node[k]; return std::min(min(a, b, (k<<1)+1, l, (l+r)>>1), min(a, b, (k<<1)+2, (l+r)>>1, r)); } long long m; int find(int a, int b, int k=0, int l=0, int r=-1){ if(r == -1){ m = min(a, b); r = N; } if(r <= a || b <= l) return INT_MAX; if(r-l == 1){ if(node[k] == m) return l; else return INT_MAX; } if(a <= l && r <= b){ int valueL = min(a, b, (k<<1)+1, l, (l+r)/2); int valueR = min(a, b, (k<<1)+2, (l+r)/2, r); if(valueL == m) return find(a, b, (k<<1)+1, l, (l+r)>>1); if(valueR == m) return find(a, b, (k<<1)+2, (l+r)>>1, r); return INT_MAX; } return std::min(find(a, b, (k<<1)+1, l, (l+r)>>1), find(a, b, (k<<1)+2, (l+r)>>1, r)); } }; int N; RMaxQ A; int M; int X[200000], Y[200000], C[200000]; ll sumC = 0; vector<pair<int,int>> s[200000]; // stars for each x RMinQ rmq; int c[200000] ={}; int bottomNode[200000]; // bottom node for each x int cnt = 0; ll dp[200000]; RMaxQ depth; ll dpChi[200000]; int dfs(int l, int r, int u){ if(l > r) return -1; int n = cnt; cnt++; int m = A.find(l, r+1); int d = A[m]+1; bottomNode[m] = n; int chi0 = dfs(l, m-1, d-1); int chi1 = dfs(m+1, r, d-1); if(chi0 != -1 && chi1 != -1){ depth.add(chi0, chi1, dp[chi1]); depth.add(chi1, cnt, dp[chi0]); } dp[n] = (chi0 != -1 ? dp[chi0] : 0) + (chi1 != -1 ? dp[chi1] : 0); dpChi[n] = dp[n]; while(rmq.min(l, r+1) <= u){ int i = rmq.find(l, r+1); int b = bottomNode[i]; dp[n] = max(dp[n], s[i][c[i]].second + depth.max(b, b+1) + dpChi[b]); c[i]++; if(c[i] < s[i].size()) rmq.update(i, s[i][c[i]].first); else rmq.update(i, N+1); } return n; } signed main(){ scanf("%d", &N); A.init(N, 0); rep(i, N){ int a; scanf("%d", &a); A.add(i, a); } scanf("%d", &M); rep(i, M){ scanf("%d%d%d", X+i, Y+i, C+i); X[i]--; s[X[i]].pb({ Y[i], C[i] }); sumC += C[i]; } rmq.init(N, N+1); rep(i, N){ if(s[i].size() == 0) continue; sort(all(s[i])); rmq.update(i, s[i][0].first); } depth.init(N, 0); dfs(0, N-1, N); printf("%lld\n", sumC-dp[0]); }

Compilation message (stderr)

constellation3.cpp: In function 'int dfs(int, int, int)':
constellation3.cpp:204:17: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<std::pair<int, int> >::size_type' {aka 'long unsigned int'} [-Wsign-compare]
  204 |         if(c[i] < s[i].size()) rmq.update(i, s[i][c[i]].first);
      |            ~~~~~^~~~~~~~~~~~~
constellation3.cpp: In function 'int main()':
constellation3.cpp:15:27: warning: unnecessary parentheses in declaration of 'i' [-Wparentheses]
   15 | #define rep(i, n) for(int (i)=0; (i)<(int)(n); (i)++)
      |                           ^
constellation3.cpp:214:5: note: in expansion of macro 'rep'
  214 |     rep(i, N){
      |     ^~~
constellation3.cpp:15:27: warning: unnecessary parentheses in declaration of 'i' [-Wparentheses]
   15 | #define rep(i, n) for(int (i)=0; (i)<(int)(n); (i)++)
      |                           ^
constellation3.cpp:220:5: note: in expansion of macro 'rep'
  220 |     rep(i, M){
      |     ^~~
constellation3.cpp:15:27: warning: unnecessary parentheses in declaration of 'i' [-Wparentheses]
   15 | #define rep(i, n) for(int (i)=0; (i)<(int)(n); (i)++)
      |                           ^
constellation3.cpp:227:5: note: in expansion of macro 'rep'
  227 |     rep(i, N){
      |     ^~~
constellation3.cpp:212:10: warning: ignoring return value of 'int scanf(const char*, ...)' declared with attribute 'warn_unused_result' [-Wunused-result]
  212 |     scanf("%d", &N);
      |     ~~~~~^~~~~~~~~~
constellation3.cpp:216:14: warning: ignoring return value of 'int scanf(const char*, ...)' declared with attribute 'warn_unused_result' [-Wunused-result]
  216 |         scanf("%d", &a);
      |         ~~~~~^~~~~~~~~~
constellation3.cpp:219:10: warning: ignoring return value of 'int scanf(const char*, ...)' declared with attribute 'warn_unused_result' [-Wunused-result]
  219 |     scanf("%d", &M);
      |     ~~~~~^~~~~~~~~~
constellation3.cpp:221:14: warning: ignoring return value of 'int scanf(const char*, ...)' declared with attribute 'warn_unused_result' [-Wunused-result]
  221 |         scanf("%d%d%d", X+i, Y+i, C+i);
      |         ~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...