1 5 1 1 5 5 1 1 2 2 3 3 4 4 5 5 3 3 1 5 1 2 4 2 3 1 5
5 4
hujie | We have carefully selected several similar problems for you: 5287 5286 5284 5279 5278
题解:用线段树维护每个点左下角内鱼的数目,因为渔网有四条边,根据限制条件的不同,需要维护四颗线段树,其限制条件分别不能从x or y 轴越过,否则该鱼不参与计数,设ans[0 ~ 3]分别为渔网右上角、左上角、右下角、左下角四个点左下方鱼的数目,则答案为: Ans = ans[0] - ans[1] - ans[2] + ans[3].
代码 I : (第一个写的,为超时版本, 正在努力修改)
#include <iostream> #include <cstdio> #include <cstring> #include <algorithm> using namespace std; #define INF 0x7ffffff #define eps 1e-8 #define maxn 100000 + 10 #define lson L, mid, rt<<1 #define rson mid+1, R, rt<<1|1 int X[4], Y[4], x[2], y[2]; int n, m; int xx[maxn], yy[maxn]; struct Node { int sum, mx, my, addx, addy; ///addx addy 相当于lazy标记 }T[4][maxn<<2]; void Pushup(int k, int rt) { int l = rt<<1, r = rt<<1|1; T[k][rt].sum = T[k][l].sum + T[k][r].sum; T[k][rt].mx = max(T[k][l].mx, T[k][r].mx); T[k][rt].my = max(T[k][l].my, T[k][r].my); } void Pushdown(int k, int rt) { int l = rt<<1, r = rt<<1|1; int t1 = T[k][rt].addx, t2 = T[k][rt].addy; T[k][l].addx += t1, T[k][r].addx += t1; T[k][l].addy += t2, T[k][r].addy += t2; T[k][l].mx += t1, T[k][r].mx += t1; T[k][l].my += t2, T[k][r].my += t2; T[k][rt].addx = T[k][rt].addy = 0; } void Bulid(int k, int L, int R, int rt) ///递归构造线段树 { T[k][rt].addx = T[k][rt].addy = 0; if(L == R) { if(xx[L]<=X[k] && yy[L]<=Y[k]) { T[k][rt].sum = 1; T[k][rt].mx = xx[L], T[k][rt].my = yy[L]; } else { T[k][rt].sum = 0; T[k][rt].mx = T[k][rt].my = -INF; } return ; } int mid = (L+R)>>1; Bulid(k, lson); Bulid(k, rson); Pushup(k, rt); } void Update(int k, int flag, int l, int r, int d, int L, int R, int rt) { if(l<=L && r>=R) { if(flag) /// 1 -- x { T[k][rt].addx += d, T[k][rt].mx += d; if(T[k][rt].mx <= X[k]) return ; } else /// 0 -- y { T[k][rt].addy += d, T[k][rt].my += d; if(T[k][rt].my <= Y[k]) return ; } if(L == R) { T[k][rt].sum = 0; T[k][rt].mx = T[k][rt].my = -INF; return ; } } int mid = (L+R)>>1; if(T[k][rt].addx || T[k][rt].addy) Pushdown(k, rt); if(r <= mid) Update(k, flag, l, r, d, lson); else if(l > mid) Update(k, flag, l, r, d, rson); else { Update(k, flag, l, mid, d, lson); Update(k, flag, mid+1, r, d, rson); } Pushup(k, rt); } int Query(int k, int l, int r, int L, int R, int rt) { if(l<=L && r>=R) return T[k][rt].sum; int mid = (L+R)>>1; if(T[k][rt].addx || T[k][rt].addy) Pushdown(k, rt); if(r <= mid) Query(k, l, r, lson); else if(l > mid) Query(k, l, r, rson); else return Query(k, l, mid, lson) + Query(k, mid+1, r, rson); } int ans[4]; int main() { int T; scanf("%d", &T); while(T--) { scanf("%d", &n);/// scanf("%d%d%d%d", &x[0], &y[0], &x[1], &y[1]); X[0] = x[1], Y[0] = y[1]; X[1] = x[0]-1, Y[1] = y[1]; X[2] = x[1], Y[2] = y[0]-1; X[3] = x[0]-1, Y[3] = y[0]-1; for(int i=1; i<=n; i++) scanf("%d%d", &xx[i], &yy[i]);/// for(int i=0; i<4; i++) Bulid(i, 1, n, 1); scanf("%d", &m);/// for(int i=0; i<m; i++) { int t, l, r, d; scanf("%d%d%d", &t, &l, &r); if(t < 3) scanf("%d", &d); if(t == 1) { for(int i=0; i<4; i++) Update(i, 1, l, r, d, 1, n, 1); } else if(t == 2) { for(int i=0; i<4; i++) Update(i, 0, l, r, d, 1, n, 1); } else { for(int i=0; i<4; i++) ans[i] = Query(i, l, r, 1, n, 1); printf("%d\n", ans[0] - ans[1] - ans[2] + ans[3]); } } } return 0; } /* 2 5 1 1 5 5 1 1 2 2 3 3 4 4 5 5 3 3 1 5 1 2 4 2 3 1 5 3 1 1 5 5 1 5 2 5 3 5 4 2 2 5 1 3 1 1 3 1 2 3 1 5 */