제출 #263298

#제출 시각아이디문제언어결과실행 시간메모리
263298KastandaPalembang Bridges (APIO15_bridge)C++11
63 / 100
2079 ms25956 KiB
// M #include<bits/stdc++.h> #define x first #define y second using namespace std; typedef long long ll; const int N = 100905 * 2; int n, k, ID[N]; ll dp[N], FA[N], FB[N], FC[N]; pair < ll , ll > FL[N], FR[N]; pair < int , int > A[N]; vector < int > U, V, S[N], E[N]; inline void AddFen(int i, int a, int b, int c) { for (i += 10; i < N; i += i & - i) FA[i] += a, FB[i] += b, FC[i] += c; } inline void AddFen(int l, int r, int a, int b, int c) { AddFen(l, a, b, c); AddFen(r, -a, -b, -c); } inline vector < ll > GetFen(int i) { vector < ll > rt = {0, 0, 0}; for (i += 10; i; i -= i & - i) rt[0] += FA[i], rt[1] += FB[i], rt[2] += FC[i]; return rt; } inline void Add(int i, int val) { // [0, ID[i]] , -U[A[i]].y , .x , .y AddFen(-2, ID[i] + 1, -U[A[i].y] * val, 0, 1 * val); // [ID[i] + 1, N) U[A[i].x] AddFen(ID[i] + 1, N, U[A[i].x] * val, -1 * val, 0); } inline ll Query(int a, int b) { ll rt = 0; rt += FL[a].x + FL[a].y * (ll)U[a]; rt += FR[b].x + FR[b].y * (ll)U[b]; int lb = (int)(lower_bound(V.begin(), V.end(), U[a] + U[b]) - V.begin()); vector < ll > tmp = GetFen(lb); rt += tmp[0]; rt += tmp[1] * (ll)U[a]; rt += tmp[2] * (ll)U[b]; return rt; } void Solve(int l, int r, int le, int ri) { if (r < l) return ; int md = (l + r) >> 1, opt = -1; // [le, l) is added ... // Extending from right to [le, md] for (int i = l; i <= md; i ++) for (int j : E[i]) if (A[j].x >= le) // Should be added Add(j, 1); // [le, md] is added, time for querying .. dp[md] = (ll)(1e18); for (int i = le; i <= min(ri, md); i ++) { ll val = Query(i, md); if (dp[md] >= val) dp[md] = val, opt = i; // Shrinking from left to [i + 1, md] for (int j : S[i]) if (A[j].y <= md) // Should be deleted Add(j, -1); } // Now we have [min(ri, md) + 1, md] // Extending from left to [opt, md] for (int i = min(ri, md); i >= opt; i --) for (int j : S[i]) if (A[j].y <= md) // Should be added Add(j, 1); Solve(md + 1, r, opt, ri); // Extending from left to [le, md] for (int i = opt - 1; i >= le; i --) for (int j : S[i]) if (A[j].y <= md) Add(j, 1); // Shrinking from right to [le, l) for (int i = md; i >= l; i --) for (int j : E[i]) if (A[j].x >= le) Add(j, -1); Solve(l, md - 1, le, opt); } int main() { ll SM = 0; cin >> k >> n; for (int i = 1; i <= n; i ++) { int a, b; //char sa[1], sb[1]; string sa, sb; //scanf("%s%d%s%d", sa, &a, sb, &b); cin >> sa >> a >> sb >> b; if (a > b) swap(a, b); SM += b - a; if (sa[0] == sb[0]) {n --; i --; continue;} SM ++; A[i] = {a, b}; U.push_back(a); U.push_back(b); V.push_back(a + b); } if (!n) return !printf("%lld\n", SM); sort(U.begin(), U.end()); U.resize(unique(U.begin(), U.end()) - U.begin()); sort(V.begin(), V.end()); V.resize(unique(V.begin(), V.end()) - V.begin()); for (int i = 1; i <= n; i ++) { ID[i] = (int)(lower_bound(V.begin(), V.end(), A[i].x + A[i].y) - V.begin()); A[i].x = (int)(lower_bound(U.begin(), U.end(), A[i].x) - U.begin()); A[i].y = (int)(lower_bound(U.begin(), U.end(), A[i].y) - U.begin()); S[A[i].x].push_back(i); E[A[i].y].push_back(i); } for (int i = 0; i < (int)U.size(); i ++) { // Sum of .y for all .y <= U[i] if (i) FL[i] = FL[i - 1]; for (int j : E[i]) FL[i].x -= U[i], FL[i].y ++; } for (int i = (int)U.size() - 1; ~ i; i --) { // Sum of .x for all .x >= U[i] FR[i] = FR[i + 1]; for (int j : S[i]) FR[i].x += U[i], FR[i].y --; } ll Mn = (ll)(1e18); for (int i = 0; i < (int)U.size(); i ++) { ll rt = 0; rt += FL[i].x + FL[i].y * (ll)U[i]; rt += FR[i].x + FR[i].y * (ll)U[i]; Mn = min(Mn, rt); } if (k == 1) return !printf("%lld\n", Mn * 2LL + SM); /*for (int a : U) printf("%d ", a); printf("\n"); for (int i = 1; i <= n; i ++) printf("(%d %d) ", A[i].x, A[i].y); printf("\n");*/ for (int i = 0; i < (int)U.size(); i ++) { dp[i] = (ll)(1e18); for (int j = i; j >= 0; j --) { for (int h : S[j]) if (A[h].y <= i) Add(h, 1); ll val = Query(j, i); if (dp[i] >= val) dp[i] = val; } for (int j = 0; j <= i; j ++) { for (int h : S[j]) if (A[h].y <= i) Add(h, -1); } } /*for (int i = 0; i < (int)U.size(); i ++) { dp[i] = (ll)(1e18); for (int j = 0; j <= i; j ++) { ll sm = 0; sm += FL[j].x + FL[j].y * (ll)U[j]; sm += FR[i].x + FR[i].y * (ll)U[i]; for (int h = 1; h <= n; h ++) { if (A[h].x > j && A[h].y < i) { if (U[j] + U[i] <= U[A[h].x] + U[A[h].y]) sm += U[i] - U[A[h].y]; else sm += U[A[h].x] - U[j]; } } dp[i] = min(dp[i], sm); } }*/ /*for (int i = 0; i < (int)U.size(); i ++) printf("%lld ", dp[i]); printf("\n");*/ //Solve(0, (int)U.size() - 1, 0, (int)U.size() - 1); for (int i = 0; i < (int)U.size(); i ++) Mn = min(Mn, dp[i]); return !printf("%lld\n", Mn * 2LL + SM); }

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

bridge.cpp: In function 'int main()':
bridge.cpp:133:26: warning: unused variable 'j' [-Wunused-variable]
  133 |                 for (int j : E[i])
      |                          ^
bridge.cpp:140:26: warning: unused variable 'j' [-Wunused-variable]
  140 |                 for (int j : S[i])
      |                          ^
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...