[ARC179E] Rectangle Concatenation

WrongAnswer_90發表於2024-08-10

My Blogs

[ARC179E] Rectangle Concatenation

唐完了。

稍微觀察一下發現矩形只有兩種形態。考慮暴力:從每個 \(i\) 開始向後掃,設 \(f_{j,0}\) 表示能否拼在左右,\(f_{j,1}\) 表示能否拼在上下。設 \(S_{l,r}\) 表示 \([l,r]\) 內矩形的面積和,沒想到用面積判就敗了:

\[\begin{aligned} f_{j,0}=(f_{j-1,0}\wedge x_j=x_{j-1})\vee(f_{j-1,1}\wedge S(i,j-1)=y_{j-1}x_j)\\ f_{j,1}=(f_{j-1,1}\wedge y_j=y_{j-1})\vee(f_{j-1,0}\wedge S(i,j-1)=x_{j-1}y_j)\\ \end{aligned} \]

考慮最佳化:把 \(j\) 從左向右掃,維護合法的 \(i\)。設 \(S_0\) 表示 \(f_{j,0}\) 合法的 \(i\) 集合,\(S_1\) 同理。發現 \(j+1\) 的時候,觀察式子左半部分,\(S_0,S_1\) 可能會做一個清空操作。

右半部分看成面積字首和相減,合法的 \(i\) 是唯一的。是一個單點加入,容易維護。還需要拿一個桶維護 \(|S_0\cup S_1|\)。時間複雜度 \(\mathcal O(n\log n)\) 或者 \(\mathcal O(n)\)

int n,s[300010],vis[300010],f0[300010],f1[300010],ans,sum;
pii a[300010];
inline void add(int x){sum+=!vis[x]++;}
inline void del(int x){sum-=!--vis[x];}
map<int,int> hash;
inline void mian()
{
	read(n),hash[0]=0;vi v0,v1;
	for(int i=1;i<=n;++i)read(a[i].fi,a[i].se),s[i]=s[i-1]+a[i].fi*a[i].se,hash[s[i]]=i;
	ans=1,add(1),add(1),v0.eb(1),v1.eb(1),f0[1]=f1[1]=1;
	for(int i=2;i<=n;++i)
	{
		int va0=1;
		if(hash.find(s[i-1]-a[i].se*a[i-1].fi)!=hash.end())va0=f0[hash[s[i-1]-a[i].se*a[i-1].fi]+1];
		int va1=1;
		if(hash.find(s[i-1]-a[i].fi*a[i-1].se)!=hash.end())va1=f1[hash[s[i-1]-a[i].fi*a[i-1].se]+1];
		if(a[i].fi!=a[i-1].fi){for(auto p:v0)del(p),f0[p]=0;v0.clear();}
		if(a[i].se!=a[i-1].se){for(auto p:v1)del(p),f1[p]=0;v1.clear();}
		int S=s[i-1]-a[i].fi*a[i-1].se;
		if(hash.find(S)!=hash.end()&&!f0[hash[S]+1]&&va1)
		add(hash[S]+1),v0.eb(hash[S]+1),f0[hash[S]+1]=1;
		S=s[i-1]-a[i].se*a[i-1].fi;
		if(hash.find(S)!=hash.end()&&!f1[hash[S]+1]&&va0)
		add(hash[S]+1),v1.eb(hash[S]+1),f1[hash[S]+1]=1;
		if(!f0[i])add(i),v0.eb(i),f0[i]=1;
		if(!f1[i])add(i),v1.eb(i),f1[i]=1;
		ans+=sum;
	}
	write(ans);
}

相關文章