https://vj.e949.cn/d8a88a967901013f7b7fe74f87ec1001?v=1544329890
对于加点的操作就看之前有多少矩形是包含他的 同样对于加矩形操作就看之前有多少点被其包含
无强制在线 考虑CDQ分治 采用两种不同的处理方法即可 都比较模板 如果强制在线只能动态主席树
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<ll,ll> pii;
const int maxn=1e5+10;
struct node0
{
ll tp,x1,y1,x2,y2;
};
struct node1
{
ll tp,x,y,val;
};
map <pii,ll> mp;
node0 pre[maxn];
node1 order[6*maxn],tmp[6*maxn];
ll sum[6*maxn],ans[maxn];
ll gou[6*maxn];
ll n,len,tot;
ll lowbit(ll x)
{
return x&(-x);
}
void update(ll tar,ll val)
{
ll i;
for(i=tar;i<=len+1;i+=lowbit(i)) sum[i]+=val;
}
ll query(ll tar)
{
ll res,i;
res=0;
for(i=tar;i>=1;i-=lowbit(i)) res+=sum[i];
return res;
}
void cdqI(ll l,ll r)
{
ll m,i,p,q,pos;
if(l==r) return;
m=(l+r)/2;
cdqI(l,m),cdqI(m+1,r);
pos=l,p=l,q=m+1;
while(p<=m&&q<=r){
if(order[p].x<=order[q].x){
if(order[p].tp==1) update(order[p].y,order[p].val);
tmp[pos++]=order[p++];
}
else{
if(order[q].tp==2) ans[order[q].val]-=query(order[q].y);
else if(order[q].tp==3) ans[order[q].val]+=query(order[q].y);
tmp[pos++]=order[q++];
}
}
while(q<=r){
if(order[q].tp==2) ans[order[q].val]-=query(order[q].y);
else if(order[q].tp==3) ans[order[q].val]+=query(order[q].y);
tmp[pos++]=order[q++];
}
for(i=l;i<=p-1;i++){
if(order[i].tp==1) update(order[i].y,-order[i].val);
}
while(p<=m) tmp[pos++]=order[p++];
for(i=l;i<=r;i++) order[i]=tmp[i];
}
void cdqII(ll l,ll r)
{
ll m,i,p,q,pos;
if(l==r) return;
m=(l+r)/2;
cdqII(l,m),cdqII(m+1,r);
pos=l,p=l,q=m+1;
while(p<=m&&q<=r){
if(order[p].x<=order[q].x){
if(order[p].tp==1) update(order[p].y,order[p].val);
tmp[pos++]=order[p++];
}
else{
if(order[q].tp==2) ans[order[q].val]+=query(order[q].y);
tmp[pos++]=order[q++];
}
}
while(q<=r){
if(order[q].tp==2) ans[order[q].val]+=query(order[q].y);
tmp[pos++]=order[q++];
}
for(i=l;i<=p-1;i++){
if(order[i].tp==1) update(order[i].y,-order[i].val);
}
while(p<=m) tmp[pos++]=order[p++];
for(i=l;i<=r;i++) order[i]=tmp[i];
}
int main()
{
pii syt;
ll i;
scanf("%lld",&n);
for(i=1;i<=n;i++){
scanf("%lld",&pre[i].tp);
if(pre[i].tp==1){
scanf("%lld%lld",&pre[i].x1,&pre[i].y1);
gou[++len]=pre[i].x1;
gou[++len]=pre[i].y1;
}
else{
scanf("%lld%lld%lld%lld",&pre[i].x1,&pre[i].y1,&pre[i].x2,&pre[i].y2);
gou[++len]=pre[i].x1,gou[++len]=pre[i].x2;
gou[++len]=pre[i].y1,gou[++len]=pre[i].y2;
}
}
sort(gou+1,gou+len+1);
len=unique(gou+1,gou+len+1)-gou-1;
for(i=1;i<=n;i++){
if(pre[i].tp==1){
pre[i].x1=lower_bound(gou+1,gou+len+1,pre[i].x1)-gou;
pre[i].y1=lower_bound(gou+1,gou+len+1,pre[i].y1)-gou;
pre[i].x1++,pre[i].y1++;
}
else{
pre[i].x1=lower_bound(gou+1,gou+len+1,pre[i].x1)-gou;
pre[i].x2=lower_bound(gou+1,gou+len+1,pre[i].x2)-gou;
pre[i].y1=lower_bound(gou+1,gou+len+1,pre[i].y1)-gou;
pre[i].y2=lower_bound(gou+1,gou+len+1,pre[i].y2)-gou;
pre[i].x1++,pre[i].y1++;
pre[i].x2++,pre[i].y2++;
}
}
tot=0;
for(i=1;i<=n;i++){
if(pre[i].tp==1){
order[++tot].tp=1,order[tot].x=pre[i].x1,order[tot].y=pre[i].y1,order[tot].val=1;
}
else{
if(pre[i].x1-1>=1) order[++tot].tp=2,order[tot].x=pre[i].x1-1,order[tot].y=pre[i].y2,order[tot].val=i;
if(pre[i].y1-1>=1) order[++tot].tp=2,order[tot].x=pre[i].x2,order[tot].y=pre[i].y1-1,order[tot].val=i;
if(pre[i].x1-1>=1&&pre[i].y1-1>=1) order[++tot].tp=3,order[tot].x=pre[i].x1-1,order[tot].y=pre[i].y1-1,order[tot].val=i;
order[++tot].tp=3,order[tot].x=pre[i].x2,order[tot].y=pre[i].y2,order[tot].val=i;
}
}
cdqI(1,tot);
/*
for(i=1;i<=n;i++){
if(pre[i].tp==1){
syt=make_pair(pre[i].x1,pre[i].y1);
ans[i]+=mp[syt];
}
else{
syt=make_pair(pre[i].x2,pre[i].y2);
mp[syt]++;
}
}
*/
tot=0;
for(i=1;i<=n;i++){
if(pre[i].tp==1){
order[++tot].tp=2,order[tot].x=pre[i].x1,order[tot].y=pre[i].y1,order[tot].val=i;
}
else{
order[++tot].tp=1,order[tot].x=pre[i].x1,order[tot].y=pre[i].y1,order[tot].val=1;
order[++tot].tp=1,order[tot].x=pre[i].x2+1,order[tot].y=pre[i].y2+1,order[tot].val=1;
order[++tot].tp=1,order[tot].x=pre[i].x1,order[tot].y=pre[i].y2+1,order[tot].val=-1;
order[++tot].tp=1,order[tot].x=pre[i].x2+1,order[tot].y=pre[i].y1,order[tot].val=-1;
}
}
memset(sum,0,sizeof(sum));
cdqII(1,tot);
for(i=1;i<=n;i++){
ans[i]+=ans[i-1];
}
for(i=1;i<=n;i++){
printf("%lld\n",ans[i]);//ll
}
return 0;
}