E.Grid
题解:这题巨水,思维难度为0,但是卡空间,你自然想到离散化,离散化肯定能过,但这题不用离散化也能过,但是你要防止递归层数过多,就要减少递归次数,具体看代码实现。
#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int maxn = 1e6 * 5 ;
ll n,m;
int tr_h[maxn] ,tr_l[maxn] ,ls_h[maxn],ls_l[maxn],rs_h[maxn],rs_l[maxn];
int cnt,cnz;
void up1(int& o,int l,int r,int ql,int qr)
{
if(!o) o = ++ cnt;
if(tr_h[o]==r-l+1)return ; //减少递归次数
if(ql<=l&&qr>=r) {
tr_h[o] = r - l + 1;
return ;
}
int mid = (l+r)/2;
if(ql<=mid) up1(ls_h[o],l,mid,ql,qr);
if(qr>mid) up1(rs_h[o],mid+1,r,ql,qr);
tr_h[o] = tr_h[ls_h[o]] + tr_h[rs_h[o]];
}
void up2(int& o,int l,int r,int ql,int qr)
{
if(!o) o = ++cnz;
if(tr_l[o]==r-l+1)return;
if(ql<=l&&qr>=r)
{
tr_l[o] = r - l + 1;
return ;
}
int mid = (l+r)/2 ;
if(ql<=mid) up2(ls_l[o],l,mid,ql,qr);
if(qr>mid) up2(rs_l[o],mid+1,r,ql,qr);
tr_l[o] = tr_l[ls_l[o]] + tr_l[rs_l[o]];
}
int main()
{
int q,op,l,r;
int f1,f2,rt1,rt2;
while(~scanf("%d%d%d",&n,&m,&q))
{
f1 = f2 = rt1 = rt2 = 0;
cnt = cnz = 0;
for(int i=1;i<=q;i++)
{
scanf("%d%d%d",&op,&l,&r);
if(op==1)
{
f1 = 1;
up1(rt1,1,n,l,r);
if(f1&&f2){
ll ans = n * m - tr_h[rt1] * m - tr_l[rt2] * (n - tr_h[rt1]) + 1;
printf("%lld\n",ans);
}
else {
ll ans = n * m - tr_h[rt1] * m + tr_h[rt1];
printf("%lld\n",ans);
}
}
else {
f2 = 1 ;
up2(rt2,1,m,l,r);
if(f1&&f2){
ll ans = n * m - tr_l[rt2] * n - tr_h[rt1] * (m-tr_l[rt2]) + 1 ;
printf("%lld\n",ans);
}
else {
ll ans = n * m - tr_l[rt2] * n + tr_l[rt2];
printf("%lld\n",ans);
}
}
}
for(int i=0;i<=cnt;i++)tr_h[i] = ls_h[i] = rs_h[i] = 0;
for(int i=0;i<=cnz;i++)tr_l[i] = ls_l[i] = rs_l[i] = 0;
}
}