E.Grid:https://ac.nowcoder.com/acm/contest/1108/E
#include<cstdio>
#include<algorithm>
using namespace std;
typedef long long ll;
const int maxn=1e6;
int sum[maxn],ls[maxn],rs[maxn];
int sum2[maxn],ls2[maxn],rs2[maxn],cnt,cnt2;
void up(int& o,int l,int r,int ql,int qr)
{
if(!o)o=++cnt; //动态开点,节点存在就不开, 节点不存在就开店
if(sum[o]==r-l+1)return; //若该区间满了就不需要再更新下去了
if(l>=ql&&r<=qr)
{
sum[o]=r-l+1;
return;
}
int m=(l+r)/2;
if(ql<=m)up(ls[o],l,m,ql,qr);
if(qr>m)up(rs[o],m+1,r,ql,qr);
sum[o]=sum[ls[o]]+sum[rs[o]];
}
void up2(int& o,int l,int r,int ql,int qr)
{
if(!o)o=++cnt2;
if(sum2[o]==r-l+1)return;
if(l>=ql&&r<=qr)
{
sum2[o]=r-l+1;
return;
}
int m=(l+r)/2;
if(ql<=m)up2(ls2[o],l,m,ql,qr);
if(qr>m)up2(rs2[o],m+1,r,ql,qr);
sum2[o]=sum2[ls2[o]]+sum2[rs2[o]];
}
int main()
{
int n,m,q,op,a,b,rt,rt2;
while(~scanf("%d%d%d",&n,&m,&q))
{
cnt=cnt2=rt=rt2=0;
while(q--)
{
scanf("%d%d%d",&op,&a,&b);
if(op==1)up(rt,1,n,a,b);
else up2(rt2,1,m,a,b);
ll ans=1ll*sum[1]*m+1ll*(n-sum[1])*sum2[1];
ans=1ll*n*m-ans+1;
if(sum[1]==0)ans=1ll*(m-sum2[1])*n+sum2[1];
if(sum2[1]==0)ans=1ll*(n-sum[1])*m+sum[1];
printf("%lld\n",ans);
}
for(int i=1;i<=cnt;i++)
sum[i]=ls[i]=rs[i]=0;
for(int i=1;i<=cnt2;i++)
sum2[i]=ls2[i]=rs2[i]=0;
}
}
恬不知耻得的抄了xls的代码,嘿嘿