Submission #352452

#TimeUsernameProblemLanguageResultExecution timeMemory
352452CaroLindaPalembang Bridges (APIO15_bridge)C++17
63 / 100
269 ms32468 KiB
#include <bits/stdc++.h>
 
#define ll long long
#define sz(x) (int)(x.size())
#define all(x) x.begin(),x.end()
 
const ll inf = 1e18 ;
const int MAXN = 1e5+10 ;
 
using namespace std ;
 
int N , K ;
long long ans ;
vector< vector<int> > sweep ;
vector< vector<int> > sweepIni ;
vector<ll> p , pref, suf, qtdPref, qtdSuf ;
multiset<tuple<ll,ll,ll> > s[2] ;
multiset<ll> ss[2] ;
ll fat ;
ll toSum[2] , toSubtract[2] , qtdSum[2] , qtdSubtract[2] , val[2] ; 
 
void add(int i, int j, int idx )
{
	for(auto e : sweep[j] )
	{
		if(e <= i ) continue ;
 
		toSubtract[idx] += p[j-1] ;
		qtdSubtract[idx]++ ;
 
		s[idx].insert( make_tuple( p[j-1] + p[e-1] - p[i-1] + fat , p[e-1] , p[j-1] ) ) ;
	}
}
 
void print(int idx )
{
	printf("Printing index %d\n", idx ) ;
	for(auto e : s[idx] ) printf("%lld %lld %lld\n", get<0>(e), get<1>(e) , get<2>(e) ) ;
	printf("toSum %lld, qtdSum %lld\ntoSubtract %lld, qtdSubtract %lld\n\n", toSum[idx], qtdSum[idx], toSubtract[idx], qtdSubtract[idx] ) ;
}
 
void compress(int i , int j,int idx )
{
	while( !s[idx].empty() && p[j-1] >= get<0>(*s[idx].begin() )-fat ) 
	{
		auto t = *s[idx].begin() ;
		s[idx].erase(s[idx].begin() ) ;
 
		toSubtract[idx] -= get<2>(t) ;
		qtdSubtract[idx]-- ;
 
		if( get<1>(t) <= p[i-1] ) continue ;
 
		toSum[idx] += get<1>(t) ;
		qtdSum[idx]++ ;
 
		ss[idx].insert( get<1>(t) ) ;
	}
	while( !ss[idx].empty() && p[i-1] >= *ss[idx].begin() ) 
	{
		toSum[idx] -= *ss[idx].begin() ;
		qtdSum[idx]-- ;
		ss[idx].erase(ss[idx].begin() ) ;
	}
}
 
ll getAns(int i, int j , int idx) { return qtdPref[i] * p[i-1] - pref[i] + suf[j] - qtdSuf[j] * p[j-1] + toSum[idx] - qtdSum[idx]*p[i-1] + qtdSubtract[idx]*p[j-1] - toSubtract[idx] ; }
 
int main()
{
	scanf("%d %d", &K , &N ) ;
 
	vector<pair<int,int> > intervals ;
 
	for(int i= 1; i <= N ; i++ )
	{
		char z1, z2 ;
		int x, y ;
		scanf(" %c %d %c %d", &z1, &x, &z2, &y ) ;
		
		if( x > y ) swap(x,y) ;
 
		ans += (ll)(y-x) ;
 
		if( z1 == z2 ) continue ;
 
		ans++ ;
 
		intervals.push_back(make_pair(x,y) ) ;
 
		p.push_back(x) ;
		p.push_back(y) ;	
 
	}
 
	sort(all(p) ) ;
	p.erase(unique(all(p) ), p.end() ) ;
 
	pref.resize( sz(p)+5 , 0 ) ; suf.resize(sz(p)+5, 0 ) ;
	qtdPref.resize(sz(p) + 5 , 0 ) ; qtdSuf.resize(sz(p)+5, 0 ) ;
 
	for(auto &e : intervals )
	{
		e.first = lower_bound(all(p), e.first ) - p.begin() + 1 ;
		e.second = lower_bound(all(p), e.second ) - p.begin() + 1 ;
 
		pref[e.second+1] += (ll)p[e.second-1] ;
		qtdPref[e.second+1]++ ;
		suf[e.first-1] += (ll)(p[e.first-1]) ;
		qtdSuf[e.first-1]++ ;
 
	}
 
	for(int i= 1 ; i <= sz(p) ; i++ ) pref[i] += pref[i-1] , qtdPref[i] += qtdPref[i-1] ;
	for(int i = sz(p) ; i >= 0 ; i-- ) suf[i] += suf[i+1] , qtdSuf[i] += qtdSuf[i+1] ;
 
	long long mn = (sz(intervals) == 0 ) ? 0 : inf ;
 
	for(int i = 1 ; i <= sz(p) ; i++ ) mn = min( mn, (qtdPref[i]-qtdSuf[i] )*p[i-1] -pref[i] + suf[i] ) ;
 
   if( sz(p) == 2 && K == 2 ) mn = 0 ;
 
	if( K == 1 || sz(p) <= 2 ) 
	{
		printf("%lld\n", ans + 2LL * mn ) ;
		return 0  ;
	}
 
	// -------------- tricky part begins here --------------
 
	sweep.resize( sz(p)+5 , vector<int>() ) ;
	sweepIni.resize( sz(p)+5 , vector<int>() ) ;
	for(auto e : intervals ) 
	{
		sweep[e.second].push_back( e.first ) ;
		sweepIni[e.first].push_back( e.second ) ;
	}
    
	add(1,1,0) ; add(1,2,0) ; 
	add(1,1,1) ; add(1,2,1) ; add(1,3,1) ;
 
	for(int opt = 2 , i = 1 ; i < sz(p) ; i++ )
   {
		
		compress(i,opt,0) ;
		if( opt+1 <= sz(p) ) compress(i,opt+1, 1) ;		
		 
	   val[0] = getAns(i,opt,0) ;
	   val[1] = (opt+1 <= sz(p) ) ?getAns(i,opt+1,1) : inf ;
 
 
		while( opt < i || (opt < sz(p) && val[1] <= val[0])  )
		{
			add(i,++opt,0) ; compress(i,opt,0) ;
			if( opt+1 <= sz(p) ) 
			{
				add(i, opt+1, 1) ;
				compress(i,opt+1, 1 ) ;
			}
 
			val[0] = getAns(i,opt,0) ;
		   val[1] = (opt+1 <= sz(p) ) ? getAns(i,opt+1,1) : inf ;
 
		 //  cout << i << " " << opt << " " << val[0] << endl ;
		}
 
 
		if( val[0] < mn ) mn = val[0] ;
 
		fat += p[i] - p[i-1] ;
 
   }
	 
	printf("%lld\n", ans + 2LL*mn ) ;
 
}

Compilation message (stderr)

bridge.cpp: In function 'int main()':
bridge.cpp:71:7: warning: ignoring return value of 'int scanf(const char*, ...)', declared with attribute warn_unused_result [-Wunused-result]
   71 |  scanf("%d %d", &K , &N ) ;
      |  ~~~~~^~~~~~~~~~~~~~~~~~~
bridge.cpp:79:8: warning: ignoring return value of 'int scanf(const char*, ...)', declared with attribute warn_unused_result [-Wunused-result]
   79 |   scanf(" %c %d %c %d", &z1, &x, &z2, &y ) ;
      |   ~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#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...