COGS 2533. [HZOI 2016]小鱼之美

我们可以发现所有的操作当中,只有坐标的增加,没有坐标的减少。

所以我们可以发现这么一个简单的事实,一条鱼一旦出了渔网,那么它就不可能再回来。

但是目前这并没有什么卵用。

 

我们可以把询问一个矩阵当中的鱼的数量转化为分别求这个矩阵的四个角的左下角的鱼的数量。又因为我们发现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\n",num[3],num[2],num[1],num[0]);
136             ll ans = num[0] - num[1] - num[2] + num[3];
137             printf("%lld\n",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 }

 

posted @ 2016-11-09 16:42  Sky_miner  阅读(266)  评论(0编辑  收藏  举报