제출 #433428

#제출 시각아이디문제언어결과실행 시간메모리
433428pliam전선 연결 (IOI17_wiring)C++14
100 / 100
112 ms14288 KiB
#include "wiring.h" #include <bits/stdc++.h> using namespace std; typedef long long ll; #define MAXN 100005 #define MAXM 100005 #define INF (ll)2e18 ll dp[MAXN+MAXM]; vector<pair<ll,int>> points;//(position,type), r=0, b=1 ll st[4*MAXN];//dp+cost rmq ll lazy[4*MAXN]; int pos; int size_seg; int m; ll pref[MAXN+MAXM]; ll solve(ll l,ll r,ll f){ return (pref[r]-pref[f-1])-(pref[f-1]-pref[l-1])+(f-l)*points[f-1].first-(r-f+1)*points[f].first+max(f-l,r-f+1)*(points[f].first-points[f-1].first); } ll solve2(int p,int n,int m_){ return solve(p-m_-n+1,p,p-m_+1); } void build(int v=1,int start=1,int end=size_seg){ lazy[v]=0; if(start==end){ ll n=start; st[v]=min(dp[pos-m-n],dp[pos-m-n+1])+solve2(pos,n,m);//pos is the first of new segment return; } int mid=(start+end)/2; build(2*v,start,mid); build(2*v+1,mid+1,end); st[v]=min(st[2*v],st[2*v+1]); } void update(int from,int to,ll val,int v=1,int start=1,int end=size_seg){ if(start==from&&end==to){ st[v]+=val; lazy[v]+=val; return; } int mid=(start+end)/2; if(lazy[v]){//propagate update(start,mid,lazy[v],2*v,start,mid); update(mid+1,end,lazy[v],2*v+1,mid+1,end); lazy[v]=0; } if(to<=mid){ update(from,to,val,2*v,start,mid); }else if(from>mid){ update(from,to,val,2*v+1,mid+1,end); }else{ update(from,mid,val,2*v,start,mid); update(mid+1,to,val,2*v+1,mid+1,end); } st[v]=min(st[2*v],st[2*v+1]); } ll min_total_length(vector<int> r, vector<int> b) { points.clear(); points.push_back({-1,-1});//numbering from 1, fake point //merge sort reverse(r.begin(),r.end()); reverse(b.begin(),b.end()); while(!r.empty()||!b.empty()){ if((!r.empty())&&(!b.empty())){ if(r.back()<b.back()){ points.push_back({r.back(),0}); r.pop_back(); }else{ points.push_back({b.back(),1}); b.pop_back(); } }else if(r.empty()){ points.push_back({b.back(),1}); b.pop_back(); }else{ points.push_back({r.back(),0}); r.pop_back(); } } pref[0]=0; for(int i=1;i<points.size();i++){ assert(points[i].first>=points[i-1].first); pref[i]=pref[i-1]+points[i].first; } dp[0]=0; pos=1; m=1; while(pos==1||points[pos-1].second==points[pos].second){ dp[pos]=INF; pos++; m++; }//found first new segment for(;pos<points.size();pos++,m++){ if(points[pos-1].second!=points[pos].second){ //entered new segment size_seg=m-1; m=1; build(); }else{ //existing segment,st needs update /* for(int n=1;n<=size_seg;n++){ ll dif=solve2(pos,n,m)-solve2(pos-1,n,m-1); if(n>=m){ assert(dif==(points[pos].first-points[pos-m+1].first)); }else{ assert(dif==(points[pos].first-points[pos-m].first)); } } */ if(m<=size_seg) update(m,size_seg,points[pos].first-points[pos-m+1].first); update(1,min(m-1,size_seg),points[pos].first-points[pos-m].first); } /* ll ans=INF; for(int n=1;n<=size_seg;n++){ ans=min(ans,min(dp[pos-m-n],dp[pos-m-n+1])+solve2(pos,n,m)); } */ dp[pos]=st[1]; //dp[pos]=ans; } return dp[points.size()-1]; }

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

wiring.cpp: In function 'll min_total_length(std::vector<int>, std::vector<int>)':
wiring.cpp:88:15: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<std::pair<long long int, int> >::size_type' {aka 'long unsigned int'} [-Wsign-compare]
   88 |  for(int i=1;i<points.size();i++){
      |              ~^~~~~~~~~~~~~~
wiring.cpp:100:10: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<std::pair<long long int, int> >::size_type' {aka 'long unsigned int'} [-Wsign-compare]
  100 |  for(;pos<points.size();pos++,m++){
      |       ~~~^~~~~~~~~~~~~~
#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...