我们可以发现所有的操作当中,只有坐标的增加,没有坐标的减少。
所以我们可以发现这么一个简单的事实,一条鱼一旦出了渔网,那么它就不可能再回来。
但是目前这并没有什么卵用。
我们可以把询问一个矩阵当中的鱼的数量转化为分别求这个矩阵的四个角的左下角的鱼的数量。又因为我们发现x和y的坐标是独立的,所以我们可以分别维护。
维护这个东西本人使用的线段树,在这里维护了八颗线段树。
然后在维护的过程中,八颗线段树应该是两两配对维护的,也就是x坐标和y坐标应该一同维护,因为我们维护的是某一个点的左下角的点的数量,所以我们在维护任意一对线段树时,如果我们发现某一个点的某一维超过了限制,那么就直接删除这个点(删除这个点的时候直接将两个坐标置为-inf)保证它不会再次影响到答案(好吧,这个性质还是有卵用的)。
这道题实际上是考察代码力。。。 。。。
1 #include <queue> 2 #include <cstdio> 3 #include <cstring> 4 #include <climits> 5 #include <algorithm> 6 using namespace std; 7 typedef long long ll; 8 template<typename T>inline void read(T &x){ 9 x=0;char ch;bool flag = false; 10 while(ch=getchar(),ch<'!');if(ch == '-') ch=getchar(),flag = true; 11 while(x=10*x+ch-'0',ch=getchar(),ch>'!');if(flag) x=-x; 12 } 13 inline ll cat_min(const ll &a,const ll &b){return a<b ? a:b;} 14 inline ll cat_max(const ll &a,const ll &b){return a>b ? a:b;} 15 const int maxn = 1000010; 16 const ll inf = LLONG_MAX>>1; 17 int n,m,X[maxn],Y[maxn]; 18 int sum[maxn<<2][4]; 19 ll max_x[maxn<<2][4],max_y[maxn<<2][4]; 20 ll lazy_x[maxn<<2][4],lazy_y[maxn<<2][4]; 21 int stander_x[4],stander_y[4]; 22 int ls,rs,dx,idx; 23 inline void push_down(int x){ 24 if(lazy_x[x][idx]){ 25 max_x[x<<1][idx] += lazy_x[x][idx]; 26 lazy_x[x<<1][idx] += lazy_x[x][idx]; 27 max_x[x<<1|1][idx] += lazy_x[x][idx]; 28 lazy_x[x<<1|1][idx] += lazy_x[x][idx]; 29 lazy_x[x][idx] = 0; 30 } 31 if(lazy_y[x][idx]){ 32 max_y[x<<1][idx] += lazy_y[x][idx]; 33 lazy_y[x<<1][idx] += lazy_y[x][idx]; 34 max_y[x<<1|1][idx] += lazy_y[x][idx]; 35 lazy_y[x<<1|1][idx] += lazy_y[x][idx]; 36 lazy_y[x][idx] = 0; 37 } 38 return ; 39 } 40 inline void update(int x){ 41 sum[x][idx] = sum[x<<1][idx] + sum[x<<1|1][idx]; 42 max_x[x][idx] = cat_max(max_x[x<<1][idx],max_x[x<<1|1][idx]); 43 max_y[x][idx] = cat_max(max_y[x<<1][idx],max_y[x<<1|1][idx]); 44 return ; 45 } 46 void build(int rt,int l,int r){ 47 lazy_x[rt][idx] = lazy_y[rt][idx] = 0; 48 if(l == r){ 49 if(X[l] <= stander_x[idx] && Y[l] <= stander_y[idx]){ 50 sum[rt][idx] = 1; 51 max_x[rt][idx] = X[l]; 52 max_y[rt][idx] = Y[l]; 53 }else{ 54 sum[rt][idx] = 0; 55 max_x[rt][idx] = -inf; 56 max_y[rt][idx] = -inf; 57 } 58 59 return; 60 } 61 int mid = l+r >> 1; 62 build(rt<<1,l,mid); 63 build(rt<<1|1,mid+1,r); 64 update(rt); 65 } 66 void modify_x(int rt,int l,int r){ 67 if(ls <= l && r <= rs){ 68 lazy_x[rt][idx] += dx; 69 max_x[rt][idx] += dx; 70 return; 71 } 72 push_down(rt); 73 int mid = l+r >> 1; 74 if(ls <= mid) modify_x(rt<<1,l,mid); 75 if(rs > mid) modify_x(rt<<1|1,mid+1,r); 76 update(rt); 77 } 78 void modify_y(int rt,int l,int r){ 79 if(ls <= l && r <= rs){ 80 lazy_y[rt][idx] += dx; 81 max_y[rt][idx] += dx; 82 return; 83 } 84 push_down(rt); 85 int mid = l+r >> 1; 86 if(ls <= mid) modify_y(rt<<1,l,mid); 87 if(rs > mid) modify_y(rt<<1|1,mid+1,r); 88 update(rt); 89 } 90 ll query(int rt,int l,int r){ 91 if(ls <= l && r <= rs) return sum[rt][idx]; 92 push_down(rt); 93 int mid = l+r >> 1; 94 if(rs <= mid) return query(rt<<1,l,mid); 95 if(ls > mid) return query(rt<<1|1,mid+1,r); 96 return query(rt<<1,l,mid) + query(rt<<1|1,mid+1,r); 97 } 98 void prse(int rt,int l,int r){ 99 if(max_x[rt][idx] <= stander_x[idx] && max_y[rt][idx] <= stander_y[idx]) return; 100 if(l == r){ 101 sum[rt][idx] = 0; 102 max_x[rt][idx] = -inf; 103 max_y[rt][idx] = -inf; 104 return; 105 } 106 push_down(rt); 107 int mid = l+r >> 1; 108 prse(rt<<1,l,mid); 109 prse(rt<<1|1,mid+1,r); 110 update(rt); 111 } 112 inline void work(){ 113 int n;read(n); 114 int x1,y1,x2,y2; 115 read(x1);read(y1);read(x2);read(y2); 116 stander_x[0] = x2;stander_y[0] = y2; 117 stander_x[1] = x1-1;stander_y[1] = y2; 118 stander_x[2] = x2;stander_y[2] = y1-1; 119 stander_x[3] = x1-1;stander_y[3] = y1-1; 120 for(int i=1;i<=n;++i) read(X[i]),read(Y[i]); 121 for(idx = 0;idx < 4;++ idx) build(1,1,n),prse(1,1,n); 122 int m;read(m); 123 for(int i=1,op;i<=m;++i){ 124 read(op);read(ls);read(rs); 125 if(op == 1){ 126 read(dx); 127 for(idx = 0;idx < 4;++idx) modify_x(1,1,n),prse(1,1,n); 128 }else if(op == 2){ 129 read(dx); 130 for(idx = 0;idx < 4;++idx) modify_y(1,1,n),prse(1,1,n); 131 }else{ 132 static ll num[4]; 133 for(idx = 0;idx < 4;++idx) 134 num[idx] = query(1,1,n); 135 // printf("I got it:: %d %d %d %d ",num[3],num[2],num[1],num[0]); 136 ll ans = num[0] - num[1] - num[2] + num[3]; 137 printf("%lld ",ans); 138 } 139 } 140 } 141 int main(){ 142 freopen("skyfishs.in","r",stdin); 143 freopen("skyfishs.out","w",stdout); 144 int T;read(T); 145 while(T--) work(); 146 getchar();getchar(); 147 fclose(stdin);fclose(stdout); 148 return 0; 149 }