Submission #67460

#TimeUsernameProblemLanguageResultExecution timeMemory
67460zscoderWiring (IOI17_wiring)C++17
0 / 100
13 ms11492 KiB
#include "wiring.h"
#include <bits/stdc++.h>

using namespace std;

typedef long long ll;
typedef vector<int> vi;
typedef pair<ll,ll> ii;

#define mp make_pair
#define pb push_back
#define fi first
#define se second

const int N = 100111;
const int M = 100111;
const int INF = int(1e9)+19;
ll dp[N+M+10];
int lastop[N+M+10]; //last opposite
ll S[N+M+10];
int lastsame[N+M+10];
int nxtsame[N+M+10];
int nxtop[N+M+10];
const int C = N+M;
vi diff[2*(N+M)+15];
int D[N+M+10];
int idxori[N+M+10];
ll sum[2][M+10];
int getid[2][M+10];
ll getS(int l, int r)
{
	if(l==0) return S[r];
	else return S[r]-S[l-1];
}

ll getsum(int id, int l, int r)
{
	if(l==0) return sum[id][r];
	else return sum[id][r]-sum[id][l-1];
}

long long min_total_length(std::vector<int> r, std::vector<int> b) 
{
	int n = r.size(); int m = b.size();
	r.pb(INF); b.pb(INF);
	vector<ii> vec;
	vec.pb(mp(-INF,-INF));
	int ptrr=0; int ptrb=0;
	int di=0;
	diff[C].pb(0); D[0]=0; 
	for(int i=0;i<n+m;i++)
	{
		if(r[ptrr]<b[ptrb])
		{
			vec.pb(mp(r[ptrr],0)); idxori[i+1]=ptrr+1; getid[0][ptrr+1]=i+1;
			ptrr++; di--;
		}
		else
		{
			vec.pb(mp(b[ptrb],1)); idxori[i+1]=ptrb+1; getid[1][ptrb+1]=i+1;
			ptrb++; di++;
		}
		diff[di+C].pb(i+1);
		D[i+1]=di;
	}
	for(int i=1;i<=r.size();i++) sum[0][i]=sum[0][i-1]+r[i-1];
	for(int i=1;i<=b.size();i++) sum[1][i]=sum[1][i-1]+b[i-1];
	lastop[0]=0;
	S[0]=0;
	for(int i=1;i<vec.size();i++) S[i]=vec[i].fi+S[i-1];
	for(int i=1;i<vec.size();i++) lastop[i]=(vec[i-1].se==vec[i].se?lastop[i-1]:i-1);
	for(int i=1;i<vec.size();i++) lastsame[i]=(vec[i-1].se==vec[i].se?i-1:lastop[i-1]);
	nxtop[int(vec.size())-1]=INF; nxtsame[int(vec.size())-1]=INF;
	for(int i=int(vec.size())-2;i>=0;i--) nxtop[i]=(vec[i].se==vec[i+1].se?nxtop[i+1]:i+1);
	for(int i=int(vec.size())-2;i>=0;i--) nxtsame[i]=(vec[i].se==vec[i+1].se?i+1:nxtop[i+1]);
	for(int i=0;i<N+M+10;i++){dp[i]=ll(1e18);}
	dp[0]=0;
	for(int i=1;i<=n+m;i++)
	{
		ll pos=vec[i].fi; int ty=vec[i].se;
		//spam opposite sides;
		{
			if(lastop[i]>0) dp[i] = min(dp[i], dp[i-1]+pos-vec[lastop[i]].fi);
			ll d=0;
			for(int k=i-1;vec[k].se==(ty^1);k--)
			{
				d+=pos-vec[k].fi;
				dp[i] = min(dp[i], dp[k-1] + d);
			}
			int ID=lower_bound(diff[D[i]+C].begin(),diff[D[i]+C].end(),i)-diff[D[i]+C].begin();
			ID--;
			if(ID>=0)
			{
				int siz = i-diff[D[i]+C][ID]; siz>>=1;
				d=getsum(ty,idxori[i]-siz+1,idxori[i])-getsum(ty^1,idxori[lastop[i]]-siz+1,idxori[lastop[i]]);
				int curb=lastsame[diff[D[i]+C][ID]+1];
				int curr=getid[ty][idxori[i]-siz];
				cerr<<"GET : "<<i<<' '<<siz<<' '<<curr<<' '<<curb<<' '<<d<<'\n';
				dp[i] = min(dp[i], dp[max(curr,curb)] + d); int nxtr=getid[ty][idxori[i]-siz+1];
				for(int k=curb;vec[k].se==(ty^1)&&vec[k].fi>vec[curr].fi;k--)
				{	
					d+=vec[nxtr].fi-vec[k].fi;
					dp[i]=min(dp[i],dp[k-1]+d);
				}
			}
			/*
			d=0; int curb=lastop[i]; int curr=i;
			while(curr>curb&&curb>0)
			{
				d+=vec[curr].fi-vec[curb].fi;
				curr=lastsame[curr]; 
				int tmpb=curb;
				curb=lastsame[curb];
				if(curr<tmpb) break;
			}
			if((curb==0&&curr==0)||(curb>0&&curr>0))
			{
				dp[i] = min(dp[i], dp[max(curr,curb)] + d);
			}
			int nxtr=nxtsame[curr];
			*/
			
			//cerr<<i<<' '<<dp[i]<<'\n';
			/*
			int p = lastop[i];
			if(p>0)
			{
				ll d = sum(p+1,i)-ll(i-p)*vec[p].fi;
				//cerr<<i<<' '<<p<<' '<<d<<'\n';
				dp[i][j] = min(dp[i][j], dp[p-1][0] + d);
				if(i-p>=2&&vec[p-1].se==vec[p].se)
				{
					dp[i][j] == min(dp[i][j], dp[p-1][1] + d - (vec[p+1].fi - vec[p].fi));
				}
			}
			*/
		}
	}
	return dp[n+m];
}

Compilation message (stderr)

wiring.cpp: In function 'long long int min_total_length(std::vector<int>, std::vector<int>)':
wiring.cpp:66:15: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
  for(int i=1;i<=r.size();i++) sum[0][i]=sum[0][i-1]+r[i-1];
              ~^~~~~~~~~~
wiring.cpp:67:15: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
  for(int i=1;i<=b.size();i++) sum[1][i]=sum[1][i-1]+b[i-1];
              ~^~~~~~~~~~
wiring.cpp:70:15: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
  for(int i=1;i<vec.size();i++) S[i]=vec[i].fi+S[i-1];
              ~^~~~~~~~~~~
wiring.cpp:71:15: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
  for(int i=1;i<vec.size();i++) lastop[i]=(vec[i-1].se==vec[i].se?lastop[i-1]:i-1);
              ~^~~~~~~~~~~
wiring.cpp:72:15: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
  for(int i=1;i<vec.size();i++) lastsame[i]=(vec[i-1].se==vec[i].se?i-1:lastop[i-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...