Submission #1284049

#TimeUsernameProblemLanguageResultExecution timeMemory
1284049trandangquangLine Town (CCO23_day1problem3)C++20
0 / 25
1 ms572 KiB
#include <bits/stdc++.h> using namespace std; #define foru(i,a,b) for(int i=(a); i<=(b); ++i) #define ford(i,a,b) for(int i=(a); i>=(b); --i) #define sz(a) (int)(a).size() #define ll long long #define _ << " " << template <class X, class Y> bool mini(X &x, Y y){return x>y?x=y,true:false;} const int N=5e5+5; int numTown,town[N]; void init(){ cin>>numTown; foru(i,1,numTown) cin>>town[i]; } vector<int> rar; void compress(){ foru(i,1,numTown) rar.emplace_back(abs(town[i])); rar.emplace_back(0); sort(rar.begin(),rar.end()); rar.erase(unique(rar.begin(),rar.end()),rar.end()); foru(i,1,numTown){ int tmp=town[i]<0 ? -1 : 1; town[i]=tmp * (lower_bound(rar.begin(),rar.end(),abs(town[i]))-rar.begin()); } } struct FenwickTree{ int f[N],tot; vector<pair<int, int>> history; void upd(int id, int val){ history.emplace_back(id,val); tot+=val; for(++id; id<N; id+=id&-id) f[id]+=val; } int getSmaller(int id){ /// or equal int res=0; for(++id; id>0; id-=id&-id) res+=f[id]; return res; } int getLarger(int id){ return tot-getSmaller(id); } void reset(){ for(auto [id,val]:history) upd(id,-val); history.clear(); } } fw1,fw2; int smallLeft[N],smallRight[N]; void countSmall(){ foru(i,1,numTown){ fw1.upd(abs(town[i]),1); smallLeft[i]=fw1.getSmaller(abs(town[i])-1); } fw1.reset(); ford(i,numTown,1){ fw1.upd(abs(town[i]),1); smallRight[i]=fw1.getSmaller(abs(town[i])-1); } fw1.reset(); } ll lastDP[2], DP[2], ansLeft[N], ansRight[N]; int id[N], signAtEven[N], useLeft[N][2], useRight[N][2]; void countAnswer(){ iota(id+1, id+1+numTown, 1); sort(id+1, id+1+numTown, [](int x, int y){return abs(town[x]) > abs(town[y]);}); foru(i,1,numTown){ signAtEven[i]=(town[i]>0 && i%2==0) || (town[i]<0 && i%2==1); /// signAtEven[i] = 1 -> > 0 } DP[0]=0; DP[1]=1e18; foru(i,1,numTown){ int l=i, r=i; while(r<=numTown && abs(town[id[r]]) == abs(town[id[l]])) ++r; --r; if(abs(town[id[r]]) == 0){ break; } vector<int> sign[2]; foru(j,l,r) sign[signAtEven[id[j]]].emplace_back(id[j]); foru(j,0,1) sort(sign[j].begin(),sign[j].end()); lastDP[0]=DP[0], lastDP[1]=DP[1]; DP[0]=DP[1]=1e18; foru(leftP,0,1){ int rightP=(numTown+i+leftP)&1; useLeft[0][0]=useLeft[0][1]=ansLeft[0]=0; foru(j,1,r-l+1){ useLeft[j][0]=useLeft[j-1][0]; useLeft[j][1]=useLeft[j-1][1]; int curUse=(leftP+j)&1; useLeft[j][curUse]++; if(useLeft[j][0]>sz(sign[0]) || useLeft[j][1] > sz(sign[1])){ ansLeft[j] = 1e18; } else{ ansLeft[j]=ansLeft[j-1]; int pos=sign[curUse][useLeft[j][curUse]-1]; ansLeft[j]+=fw1.getLarger(pos)+smallLeft[pos]; fw1.upd(pos, 1); } } fw1.reset(); useRight[r-l+2][0]=useRight[r-l+2][1]=ansRight[r-l+2]=0; ford(j,r-l+1,1){ useRight[j][0]=useRight[j+1][0]; useRight[j][1]=useRight[j+1][1]; int curUse=(rightP+(r-l+1-j))&1; useRight[j][curUse]++; if(useRight[j][0]>sz(sign[0]) || useRight[j][1] > sz(sign[1])){ ansRight[j] = 1e18; } else{ ansRight[j]=ansRight[j+1]; int pos=sign[curUse][sz(sign[curUse])-useRight[j][curUse]]; ansRight[j]+=fw2.getSmaller(pos)+smallRight[pos]; fw2.upd(pos, 1); } } ll cur=0; foru(j,0,r-l+1){ if(j>=1){ int curUse=(leftP+j)&1; if(useLeft[j][curUse] <= sz(sign[curUse])){ int pos = sign[curUse][useLeft[j][curUse]-1]; cur -= fw1.getLarger(pos); fw2.upd(pos, -1); cur += fw2.getSmaller(pos); fw1.upd(pos, 1); } } if(useLeft[j][0]+useRight[j+1][0]==sz(sign[0]) && useLeft[j][1]+useRight[j+1][1]==sz(sign[1])){ mini(DP[(leftP+j)&1], lastDP[leftP] + ansLeft[j]+ansRight[j+1]+cur); } } fw1.reset(); fw2.reset(); } i=r; } cout<<((min(DP[0],DP[1])==(ll)1e18)?-1:min(DP[0],DP[1]))<<'\n'; } void solve(){ compress(); countSmall(); countAnswer(); } int main(){ init(); solve(); }
#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...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...