域名网站注册认证,德州网站制作公司,个性化企业网站制作公司,江苏省建设教育协会网站首页铺地毯problemsolutioncodeproblem
给定矩阵的长宽 P,QP,QP,Q#xff0c;矩阵从下往上从左往后编号增加#xff0c;(0,0)∼(P,Q)(0,0)\sim (P,Q)(0,0)∼(P,Q)。
给定 nnn 张长宽平行于坐标轴的矩形地毯#xff0c;左下角和右上角的坐标。
求被至少 n−1n-1n−1 张地毯覆盖…
铺地毯problemsolutioncodeproblem
给定矩阵的长宽 P,QP,QP,Q矩阵从下往上从左往后编号增加(0,0)∼(P,Q)(0,0)\sim (P,Q)(0,0)∼(P,Q)。
给定 nnn 张长宽平行于坐标轴的矩形地毯左下角和右上角的坐标。
求被至少 n−1n-1n−1 张地毯覆盖到的格子数量。
n≤3e5,P,Q≤1e9n\le 3e5,P,Q\le 1e9n≤3e5,P,Q≤1e9。
solution
矩形欸算的也是矩形相关的覆盖面积。
树套树 nlog2nn\log^2nnlog2n扫描线 nlognn\log nnlogn。笑死根本写不动。
observation1任何矩形的交最后一定也是平行于坐标轴的矩形或为空。
observation2矩形的交不可逆即不能将所有矩形交起来再去掉其中一个得到 n−1n-1n−1 个矩形的交。
对于矩阵序列计算前缀交和后缀交然后排除掉第 iii 个矩形。
即算 [1,i)⋂(i,n][1,i)\bigcap(i,n][1,i)⋂(i,n] 的矩形的交然后计算给答案。
这样就计算了每 n−1n-1n−1 个矩形的交。
但是如果某些部分是 nnn 个矩形的交就会被计算 nnn 次最后去重一下减掉 n−1n-1n−1 次的计算结果即可。
code
#include bits/stdc.h
using namespace std;
#define maxn 300005
int P, Q, n, T;
struct node {int l1, r1, l2, r2;friend node cross( node x, node y ) {return { max( x.l1, y.l1 ), max( x.r1, y.r1 ), min( x.l2, y.l2 ), min( x.r2, y.r2 ) };}long long calc() { if( l1 l2 or r1 r2 ) return 0;else return 1ll * ( l2 - l1 ) * ( r2 - r1 );}
}matrix[maxn], pre[maxn], suf[maxn];int main() {freopen( carpet.in, r, stdin );freopen( carpet.out, w, stdout );scanf( %d, T );while( T -- ) {scanf( %d %d %d, P, Q, n );for( int i 1, l1, r1, l2, r2;i n;i ) {scanf( %d %d %d %d, l1, r1, l2, r2 );matrix[i] { l1, r1, l2, r2 };}if( n 1 ) { printf( %lld\n, matrix[1].calc() ); continue; }long long ans 0;pre[1] matrix[1], suf[n] matrix[n];for( int i 2;i n;i ) pre[i] cross( pre[i - 1], matrix[i] );for( int i n - 1;i;i -- ) suf[i] cross( suf[i 1], matrix[i] );ans pre[n - 1].calc();ans suf[2].calc();for( int i 2;i n;i ) ans cross( pre[i - 1], suf[i 1] ).calc();ans - ( n - 1 ) * pre[n].calc();printf( %lld\n, ans );}return 0;
}