题解--超越维度
吐槽自己,出这么偏的题。
但部分分还是给足了的。
但为什么比赛时没几个人A啊?
10pts
乱搞就可以了,入门难度。
30pts
建一个二维线段树,区块赋值,区块查询,然后就相当于模板了。
60pts
建一个三维线段树,其他和30pts做法一样。
100pts
介绍一下这个题所用的冷门算法:矩形切割。
矩形切割,就是将它有相交部分的矩形分割成若干个小矩形,从而消除重叠的部分,方便计算面积。当然,其它维度也是一样的。由于每次插入和查询时都要遍历一遍已经存在的所有矩形,所有时间复杂度是
为了方便,就以二维的情况为进行一次模拟操作,其它维度也是一个道理。
假设这里有一个矩形 A 和一个矩形 B,它们是相交的(不相交的情况直接忽略)
所谓的矩形切割,就是删除原来的 A,替换成全新的 A1 和 A2,这样,每一个矩形之间就没有相交的部分,所以计算面积就可以直接把所有的矩形的面积加起来,就可以得到答案。
接下来就可以看代码了。
#include <bits/stdc++.h>
using namespace std;
namespace io {
inline long long read() {
long long __x=0,__f=1;
char __c=getchar();
while(__c<'0'||__c>'9') {
if(__c=='-')__f=-1;
__c=getchar();
}
while(__c>='0'&&__c<='9') {
__x=__x*10+__c-'0';
__c=getchar();
}
return __x*__f;
}
char __F[200];
inline void write(long long __x) {
if(__x==0) {
putchar('0');
return;
}
long long __tmp,__cnt=0;
if(__x>0) {
__tmp=__x;
} else {
__tmp=-__x;
}
if(__x<0) {
putchar('-');
}
while(__tmp>0) {
__F[__cnt++]=__tmp%10+'0';
__tmp/=10;
}
while(__cnt>0) {
putchar(__F[--__cnt]);
}
}
}
using namespace io;//快速读入,可忽略。
struct square {
long long x[10],y[10];//x=左上每个维度坐标,y=右下每个维度坐标
} s[1000005];
long long n,k,cnt;
long long ans,mod=1919810;
bool pd(square a,square b) {
for(register long long i=1; i<=k; i++) {
if(a.x[i]>=b.y[i]||a.y[i]<=b.x[i]) {
return 0;//只要有一个维度上它们最多在边界擦过,那它们就不相交了,直接忽略。
}
}
return 1;
}
void add(square q) {
cnt++;
for(register long long i=1; i<=k; i++) {
s[cnt].x[i]=q.x[i];
s[cnt].y[i]=q.y[i];
}//加入一个新k维体。
}
void del(int now) {
s[now]=s[cnt--];//把最后一个替换成当前这一个,再删除最后一个,相当于删除了now上的k维体。
}
void cut(square a,square b,int i) {
if(i==k+1)return;
long long k1,k2;
square q;
k1=max(a.x[i],b.x[i]);
k2=min(a.y[i],b.y[i]);
if(k1>a.x[i]) {
q=a;
q.y[i]=k1;
add(q);//这个维度相交的话,加一个新的。
}
if(k2<a.y[i]) {
q=a;
q.x[i]=k2;
add(q);//同理。
}
a.x[i]=k1;
a.y[i]=k2;//记录切到哪里了。
cut(a,b,i+1);//往下一个维度走。
}
long long sum(long long j,square q) {
long long m=1;
for(register long long i=1; i<=k; i++) {
m=m*(min(s[j].y[i],q.y[i])-max(s[j].x[i],q.x[i]));//计算k维体积。
m%=mod;
}
return m;
}
int main() {
long long a[10],w,x;
square q;
n=read(),k=read();
for(register long long i=1; i<=n; i++) {
x=read();
for(register long long j=1; j<=k; j++) {
a[j]=read();
}
w=read();
for(register long long j=1; j<=k; j++) {
q.x[j]=a[j]-w;
q.y[j]=a[j]+w;
}
if(x==1) {
for(register long long j=1; j<=cnt; j++) {
if(pd(q,s[j])) {
cut(s[j],q,1);
del(j);
j--;//切完之后再删除。
}
}
add(q);
} else {
ans=0;
for(register long long j=1; j<=cnt; j++) {
if(pd(q,s[j])) {
ans+=sum(j,q);//与它相交的话才加相交部分
ans%=mod;
}
}
write(ans);
putchar('\n');
}
}
return 0;
}