Submission #847150

#TimeUsernameProblemLanguageResultExecution timeMemory
847150oneloveforeverClosing Time (IOI23_closing)C++17
8 / 100
143 ms42892 KiB
//#include "closing.h" #include <bits/stdc++.h> using namespace std; #define x first #define y second #define ll long long const long long inf=1e18+7; using Graph = vector<vector<pair<int, long long>>> ; template<typename T> bool maximize(T &a,T b) { if(a<b) { a=b; return true; } return false; } void dfs(int x,int par,Graph &edge,vector<ll>&dist) { for(auto [node,value]:edge[x]) { if(node==par)continue; dist[node]=dist[x]+value; dfs(node,x,edge,dist); } } int Sub1(int N,long long K,vector<ll>distX,vector<ll>distY) { vector<ll>que; for(int i=1; i<=N; i++) { que.push_back(distX[i]); que.push_back(distY[i]); } sort(que.begin(),que.end()); ll res=K; int ans=0; for(int value:que) { if(res<value)break; res-=value; ans++; } return ans; } bool checkLinear(int N,Graph &edge,vector<int>&deg) { int maxv=0; for(int i=1;i<=N;i++) { for(auto [node,value]:edge[i]) { deg[node]++; maxv=max(maxv,deg[node]); } } return maxv<=2; } struct IT { int n; vector<pair<long long,int> >bit; IT(int _n=0) { n=_n; bit.resize(n+7); } void update(int index,pair<long long,int>value) { for(;index<=n;index+=(index&(-index))) { bit[index].x+=value.x; bit[index].y+=value.y; } } pair<long long,int>calc(int index) { pair<long long ,int>value; for(;index;index-=(index&(-index))) { value.x+=bit[index].x; value.y+=bit[index].y; } return value; } pair<long long,int>get(int x,int y) { pair<long long,int>value_x=calc(x-1); pair<long long,int>value_y=calc(y); pair<long long,int>ans; ans.x=value_y.x-value_x.x; ans.y=value_x.y-value_y.y; return ans; } }; int Sub2(int N,int X,int Y,long long K,Graph &edge,vector<int>deg,vector<long long>distX,vector<long long>distY) { int need_node; if(deg[X]>deg[Y])swap(X,Y); for(int i=1;i<=N;i++)if(deg[i]==1) { need_node=i; break; } vector<int>beg(N+1,0); vector<int>pos(N+1); beg[need_node]=1; queue<int>q; q.push(need_node); while(!q.empty()) { int x=q.front(); pos[beg[x]]=x; q.pop(); for(auto [node,value]:edge[x]) { if(!beg[node]) { beg[node]=beg[x]+1; q.push(node); } } } vector<long long>sumX(N+1); vector<long long>sumY(N+1); for(int i=1;i<=N;i++) { sumX[i]=sumX[i-1]+min(distX[i],distY[i]); sumY[i]=sumY[i-1]+max(distX[i],distY[i]); } vector<int>que; for(int i=1;i<=N;i++) { que.push_back(distX[i]); que.push_back(distY[i]); } sort(que.begin(),que.end()); vector<int>num(2*N+1,0); vector<int>posX(N+1),posY(N+1); for(int i=1;i<=N;i++) { int index_x=lower_bound(que.begin(),que.end(),distX[pos[i]])-que.begin()+1; int index_y=lower_bound(que.begin(),que.end(),distY[pos[i]])-que.begin()+1; if(!num[index_x])num[index_x]=index_x; else num[index_x]++; if(!num[index_y])num[index_y]=index_y; else num[index_y]++; posX[i]=num[index_x]; posY[i]=num[index_y]; } int ans=0; long long res=K; for(long long value:que) { if(value>res)break; ans++; res-=value; } IT s(2*N); for(int i=1;i<=N;i++) { for(int cnt=1;cnt<=min(i,beg[X])-1;cnt++)s.update(posX[cnt],make_pair(distX[cnt],1)); for(int cnt=beg[Y]+1;cnt<=N;cnt++)s.update(posY[cnt],make_pair(distY[cnt],1)); for(int j=i;j<=N;j++) { if(j>beg[Y])s.update(posY[j],make_pair(-distY[j],-1)); long long value=sumY[j]-sumY[i-1]; int total=(j-i+1)*2; if(i-1>=beg[X]) { total+=(i-beg[X]); value+=sumX[i-1]-sumX[beg[X]-1]; } if(j<=beg[Y]) { total+=(beg[Y]-j); value+=sumX[beg[Y]]-sumX[j]; } if(value>K)continue; long long used=K-value; int x=1; int y=2*N; int res=0; while(x<=y) { int mid=(x+y)/2; pair<long long,int> value=s.get(1,mid); if(value.x<=used) { res=value.y; x=mid+1; } else y=mid-1; } ans=max(ans,total+res); } for(int cnt=1;cnt<=min(i,beg[X])-1;cnt++)s.update(posX[cnt],make_pair(-distX[cnt],-1)); } return ans; } int max_score(int N,int X,int Y,long long K,vector<int>U,vector<int>V,vector<int>W) { X+=1; Y+=1; Graph edge(N+1); for(int i=1; i<=N-1; i++) { int x=U[i-1]+1; int y=V[i-1]+1; int value=W[i-1]; edge[x].push_back({y,value}); edge[y].push_back({x,value}); } vector<ll>distX(N+1); vector<ll>distY(N+1); dfs(X,0,edge,distX); dfs(Y,0,edge,distY); if(distX[Y]>2*K)return Sub1(N,K,distX,distY); vector<int>deg(N+1); if(checkLinear(N,edge,deg))return Sub2(N,X,Y,K,edge,deg,distX,distY); } /*signed main() { int n,x,y,k; vector<int>U; vector<int>V; vector<int>W; cin>>n>>x>>y>>k; for(int i=1; i<=n-1; i++) { int x; cin>>x; U.push_back(x); } for(int i=1; i<=n-1; i++) { int y; cin>>y; V.push_back(y); } for(int i=1; i<=n-1; i++) { int value; cin>>value; W.push_back(value); } cout<<max_score(n,x,y,k,U,V,W); } */

Compilation message (stderr)

closing.cpp: In function 'int max_score(int, int, int, long long int, std::vector<int>, std::vector<int>, std::vector<int>)':
closing.cpp:208:19: warning: control reaches end of non-void function [-Wreturn-type]
  208 |     Graph edge(N+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...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...