Submission #1228618

#TimeUsernameProblemLanguageResultExecution timeMemory
1228618denislavNile (IOI24_nile)C++20
100 / 100
112 ms28216 KiB
# include <iostream> # include <vector> # include <algorithm> # include <cassert> # define all(x) x.begin(),x.end() using namespace std; # include "nile.h" //# include "grader.cpp" const long long INF=1e18; const int MAX=1e5+11,LOG=20; int n,q; long long s; pair<int,long long> a[MAX]; long long pref[MAX]; int even[MAX][LOG]; int odd[MAX][LOG]; void sparse_table() { for(int i=1;i<=n;i++) { if(i%2==0) { even[i][0]=a[i].second; odd[i][0]=1e9; } else { even[i][0]=1e9; odd[i][0]=a[i].second; } } for(int j=1;j<LOG;j++) { for(int i=1;i+(1<<j)-1<=n;i++) { even[i][j]=min(even[i][j-1],even[i+(1<<(j-1))][j-1]); odd[i][j]=min(odd[i][j-1],odd[i+(1<<(j-1))][j-1]); } } } int Even(int l, int r) { int j=31-__builtin_clz(r-l+1); return min(even[l][j],even[r-(1<<j)+1][j]); } int Odd(int l, int r) { int j=31-__builtin_clz(r-l+1); return min(odd[l][j],odd[r-(1<<j)+1][j]); } int tree[MAX*4]; void build(int v=1, int l=1, int r=n) { if(l==r) { tree[v]=1e9; return ; } int mid=(l+r)/2; build(v*2,l,mid); build(v*2+1,mid+1,r); tree[v]=min(tree[v*2],tree[v*2+1]); } void update(int pos, int v=1, int l=1, int r=n) { if(l==r) { tree[v]=a[pos].second; return ; } int mid=(l+r)/2; if(pos<=mid) update(pos,v*2,l,mid); else update(pos,v*2+1,mid+1,r); tree[v]=min(tree[v*2],tree[v*2+1]); } int query(int le, int ri, int v=1, int l=1, int r=n) { if(ri<l or r<le) return 1e9; if(le<=l and r<=ri) return tree[v]; int mid=(l+r)/2; return min(query(le,ri,v*2,l,mid),query(le,ri,v*2+1,mid+1,r)); } long long calc(int l, int r) { if((r-l+1)%2==0) return pref[r]-pref[l-1]; int ans=min(a[l].second,a[r].second); if(l%2==0) ans=min(ans,Even(l,r)); else ans=min(ans,Odd(l,r)); ans=min(ans,query(l,r)); return pref[r]-pref[l-1]-ans; } int sz[MAX]; int par[MAX]; int le[MAX]; int ri[MAX]; long long cost[MAX]; void init() { for(int i=1;i<=n;i++) { sz[i]=1; par[i]=i; le[i]=i; ri[i]=i; cost[i]=0; } } int root(int u) { if(par[u]==u) return u; else return par[u]=root(par[u]); } void unite(int u, int v) { u=root(u); v=root(v); if(u==v) return ; if(sz[u]<sz[v]) swap(u,v); s+=cost[u]+cost[v]; le[u]=min(le[u],le[v]); ri[u]=max(ri[u],ri[v]); par[v]=u; sz[u]+=sz[v]; cost[u]=calc(le[u],ri[u]); s-=cost[u]; } std::vector<long long> calculate_costs(std::vector<int> W, std::vector<int> A, std::vector<int> B, std::vector<int> E) { n=W.size();q=E.size(); for(int i=0;i<n;i++) { a[i+1]={W[i],A[i]-B[i]}; s+=A[i]; } sort(a+1,a+n+1); for(int i=1;i<=n;i++) pref[i]=pref[i-1]+a[i].second; vector<pair<int,int>> qrs,items,avail; vector<long long> Final(q); for(int i=1;i<n;i++) items.push_back({a[i+1].first-a[i].first,i}); for(int i=2;i<n;i++) avail.push_back({a[i+1].first-a[i-1].first,i}); for(int i=0;i<q;i++) qrs.push_back({E[i],i}); sort(all(items)); sort(all(avail)); sort(all(qrs)); init(); build(); sparse_table(); int ptr=0,ptr2=0; for(pair<int,int> PA: qrs) { int w=PA.first,id=PA.second; while(ptr<(int)items.size() and items[ptr].first<=w) { int x=items[ptr].second; unite(x,x+1); ptr++; //cout<<x<<"->"<<s<<"\n"; } while(ptr2<(int)avail.size() and avail[ptr2].first<=w) { int x=avail[ptr2].second; update(x); int rt=root(x); s+=cost[rt]; cost[rt]=calc(le[rt],ri[rt]); s-=cost[rt]; ptr2++; //cout<<x<<"-->"<<s<<"\n"; //if(x==3) cout<<query(3,3)<<"\n"; } Final[id]=s; } return Final; } /** 5 15 5 1 12 4 2 2 5 2 10 6 3 21 3 2 3 5 9 1 */
#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...