kmjp's blog

競技プログラミング参加記です

yukicoder : No.1347 HS Railway

うーむ…。
https://yukicoder.me/problems/no/1347

問題

N個の駅が順に並んでおり、そこで5種類の電車が運行される。
各電車は、それぞれ定められた始発駅から終着駅まで走行する。走行の向きは全列車同じである。
その際、5種類の電車毎の速度は昇順となることがわかっている。

今ここでM台の電車が運行し、各電車の出発時刻と種類が与えられる。
同じ場所にいる時間があるような電車対は何組あるか。

解法

種類の対ごとに考える。
今、2種類の電車が共通して走行する駅の区間が[L,R]とする。
速い方の電車を総当たりし、それぞれRの到着時刻を求めよう。
すると、遅い方の電車について、L通過時は速い方の電車の出発前で、R到着時は速い方の電車の出発後であるような出発時刻の区間を求めることができる。
あとは遅い方の電車の出発時間を昇順ソートしておけば、二分探索で出発時刻の区間に合致する電車の数を求めることができる。

int N,M;
ll L[5],R[5],A[5][101010];
vector<ll> B[101010];

void solve() {
	int i,j,k,l,r,x,y; string s;
	cin>>N;
	FOR(i,5) {
		cin>>L[i]>>R[i];
		for(j=L[i];j<R[i];j++) cin>>A[i][j];
	}
	cin>>M;
	FOR(i,M) {
		cin>>x>>y;
		B[x-1].push_back(y-1);
	}
	FOR(i,5) sort(ALL(B[i]));
	ll ret=0;
	FOR(y,5) FOR(x,y) {
		vector<ll> cand;
		if(R[y]<L[x]||R[x]<L[y]) continue;
		int TL=max(L[x],L[y]);
		int TR=min(R[x],R[y]);
		ll D=0,DC=0;
		for(i=L[x];i<TL;i++) DC+=A[x][i];
		FORR(b,B[x]) cand.push_back(DC+b);
		DC=0;
		for(i=L[y];i<TL;i++) DC+=A[y][i];
		for(i=TL;i<TR;i++) D+=A[y][i]-A[x][i];
		FORR(b,B[y]) {
			ll s=b+DC;
			ll t=s+D+1;
			ret+=lower_bound(ALL(cand),t)-lower_bound(ALL(cand),s);
			
		}
	}
	cout<<ret<<endl;
	
}

まとめ

難易度の割にAC数が少ない気がする。