It is easy to find a O (n- 2 ) the DP, F [I] [J] = F [I] [J +. 1] + F [I +. 1] [J] -f [I +. 1] [+ J. 1] . Then because of the fence, some locations can not go, then you can use a similar difference method, f [i] represents the current row f [i + 1] flowers can not be reached, then find the first fence below for each point . Points of discussion, the need to support a single point of modification (flowers appear), section flag covering (the emergence of a fence), and a range of zero (the fence is gone), of course, range queries (cow appeared), then we have to support first th obstacle inquiry, but these operations with a more tree line can be run through the complexity of a log can "easily" ran.
#include<cstdio> #include<algorithm> #define lson l,mid,rt<<1 #define rson mid+1,r,rt<<1|1 using namespace std; const int N=2e6+7,M=1e6; struct fence{int xl,xr,y,i;bool tp;}a[N<<1]; bool operator<(fence a,fence b){return a.y!=b.y?a.y>b.y:a.xl<b.xl;} struct flower{int x,y;}b[N]; bool operator<(flower a,flower b){return a.y>b.y;} struct cow{int x,y,i;}c[N]; bool operator<(cow a,cow b){return a.y>b.y;} struct seg{int num;bool cov,cut;}tr[N<<2]; int n,m,val[N],ans[N]; void pushup(int rt) { tr[rt].num=tr[rt<<1].num+tr[rt<<1|1].num; tr[rt].cut=tr[rt<<1].cut|tr[rt<<1|1].cut; } void modify(int rt){tr[rt].cov=1,tr[rt].num=0;} void pushdown(int rt){if(tr[rt].cov)modify(rt<<1),modify(rt<<1|1),tr[rt].cov=0;} void add(int k,int v,int l,int r,int rt) { tr[rt].num+=v; if(l==r)return; pushdown(rt); int mid=l+r>>1; if(k<=mid)add(k,v,lson);else add(k,v,rson); pushup(rt); } void cover(int L,int R,int l,int r,int rt) { if(L<=l&&r<=R){modify(rt);return;} pushdown(rt); int mid=l+r>>1; if(L<=mid)cover(L,R,lson); if(R>mid)cover(L,R,rson); pushup(rt); } int query(int L,int R,int l,int r,int rt) { if(L<=l&&r<=R)return tr[rt].num; pushdown(rt); int mid=l+r>>1,ret=0; if(L<=mid)ret+=query(L,R,lson); if(R>mid)ret+=query(L,R,rson); return ret; } void update(int k,int l,int r,int rt) { if(l==r){tr[rt].cut^=1;return;} pushdown(rt); int mid=l+r>>1; if(k<=mid)update(k,lson);else update(k,rson); pushup(rt); } int getnxt(int L,int l,int r,int rt) { if(l>=L) { if(tr[rt].cut) { while(l!=r) if(tr[rt<<1].cut)rt<<=1,r=l+r>>1; else rt=rt<<1|1,l=(l+r>>1)+1; return l; } return 0; } int tmp,mid=l+r>>1; pushdown(rt); if(L<=mid&&(tmp=getnxt(L,lson)))return tmp; return getnxt(L,rson); } int main() { int f;scanf("%d",&f); for(int i=0,x1,y1,x2,y2;i<f;i++) { scanf("%d%d%d%d",&x1,&y1,&x2,&y2); a[i<<1]=(fence){x1,x2,y1-1,i,0}; a[i<<1|1]=(fence){x1,x2,y2,i,1}; } sort(a,a+(f<<1)); scanf("%d",&m); for(int i=1;i<=m;i++)scanf("%d%d",&b[i].x,&b[i].y); sort(b+1,b+m+1); scanf("%d",&n); for(int i=1;i<=n;i++)scanf("%d%d",&c[i].x,&c[i].y),c[i].i=i; sort(c+1,c+n+1); f=0; update(M,1,M,1); for(int i=M,p=1,q=1;i;i--) { int sum,cut; while(a[f].y==i) { if(!a[f].tp) { cover(a[f].xl,a[f].xr,1,M,1); if(a[f].xl!=1)add(a[f].xl-1,-val[a[f].i],1,M,1); if(a[f].xl!=1)update(a[f].xl-1,1,M,1); if(a[f].xr!=M)update(a[f].xr,1,M,1); } else{ cut=getnxt(a[f].xr,1,M,1),sum=query(a[f].xl,a[f].xr,1,M,1); val[a[f].i]=query(a[f].xr+1,cut,1,M,1); cover(a[f].xl,a[f].xr,1,M,1); if(a[f].xl>1)add(a[f].xl-1,sum+val[a[f].i],1,M,1); if(a[f].xl!=1)update(a[f].xl-1,1,M,1); if(a[f].xr!=M)update(a[f].xr,1,M,1); } f++; } while(b[p].y==i)add(b[p].x,1,1,M,1),++p; while(c[q].y==i)cut=getnxt(c[q].x,1,M,1),ans[c[q].i]=query(c[q].x,cut,1,M,1),++q; } for(int i=1;i<=n;i++)printf("%d\n",ans[i]); }