洛谷3801-红色的幻想乡-线段树
3801-红色的幻想乡
考虑到二维线段树没法处理1e5^2的数据,把它压成一维的。
对于任意一次喷出喷雾,可以看成对横向的一条线段和竖向的一条线段都染上色,再考虑横竖相交的情况,如果把原来喷吐喷雾的位置看成两条线段相交,可以所有横竖相交的点的数量就是横向线段的数量和竖线的数量乘积。同时由于可能有多次在同一排上喷出喷雾,画图发现喷两次相当于这条线段被抹去,所以修改的时候可以异或原值,分别修改横纵坐标的值,这就是线段树的单点修改了。查询的时候找出询问的长和宽的线段数目,相乘之后减去重合点即可。
注意开成一个线段树的时候横纵坐标要分清楚,,
另由于最高可以达到1e5^2,需要开LL
#include <bits/stdc++.h>
using namespace std;
#define ios ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
#define endl '\n'
//#define int ll
#define debugg(x) cout<<#x<<'='<<x<<endl;
#define debug1(x,y,z) cout<<#x<<' '<<x<<' '<<#y<<' '<<y<<' '<<#z<<' '<<z<<endl;
#define debug cout<<endl<<"********"<<endl;
#define ll long long
#define int ll
#define ull unisgned long long
#define ld long double
#define itn int
#define pii pair<int,int>
#define rep(I, A, B) for (int I = (A); I <= (B); ++I)
#define dwn(I, A, B) for (int I = (A); I >= (B); --I)
#define mod (ll)(1e9+7)
//#define mid ((lo+ro)>>1)
void fre(){
freopen("test.in","r",stdin);
freopen("test.out","w",stdout);
}
void fc(){fclose(stdin);fclose(stdout);}
const int maxn=3e5+10;
const ll inf=0x7fffffff;
struct node{
int zhi;int lo;int ro;
}all[maxn*4];
int n,m,q;
ll req(int now,int lo,int ro){
if(all[now].lo>=lo&&all[now].ro<=ro) return all[now].zhi;
if(all[now].lo>ro||all[now].ro<lo) return 0;
int mid=(all[now].lo+all[now].ro)/2;
ll ans=0;
if(mid>=lo) ans+=req(now*2,lo,ro);
if(mid<ro) ans+=req(now*2+1,lo,ro);
return ans;
}
void upd(int now,int pos){
if(all[now].lo==all[now].ro&&all[now].lo==pos){all[now].zhi=(all[now].zhi==1)?0:1;return;}
int mid=(all[now].lo+all[now].ro)/2;
if(pos<=mid) upd(now*2,pos);
else upd(now*2+1,pos);
all[now].zhi=all[now*2].zhi+all[now*2+1].zhi;
}
void build(int now,int lo,int ro){
all[now].lo=lo;all[now].ro=ro;
if(lo==ro) return;
int mid=(lo+ro)/2;
build(now*2,lo,mid);
build(now*2+1,mid+1,ro);
}
signed main(){
ios;fre();
cin>>n>>m>>q;
build(1,1,n+m);
while(q--){
int a1;cin>>a1;
if(a1==1){
int x,y;cin>>x>>y;upd(1,x+m);upd(1,y);
}
else{
int s1,s2,d1,d2;cin>>s1>>d1>>s2>>d2;
int ans1=req(1,s1+m,s2+m);int ans2=req(1,d1,d2);
cout<<(int)(ans1*(ll)(d2-d1+1)+ans2*(ll)(s2-s1+1)-2LL*(ans1*ans2))<<endl;
}
}
return 0;
}

浙公网安备 33010602011771号