[BZOJ4422] [Cerc2015]Cow Confinement

[BZOJ4422] [Cerc2015]Cow Confinement

Description

一个10^6行10^6列的网格图,上面有一些牛、花和一些矩形围栏,围栏在格子的边界上,牛和花在格子里,牛只能向下或向右走,牛也不能穿过围栏和地图边界,求每头牛它能到达的花的数量。注意栅栏不会相交

Input

第一行一个数f表示矩形围栏的数量。接下来f行,每行四个数x1,y1,x2,y2,表示(x1,y1)在围栏内部矩形的左上角,(x2,y2)在右下角。接下来一行一个数m表示花的数量。接下来m行每行两个数x,y,表示在(x,y)处有一朵花。接下来一行一个数n表示牛的数量。接下来n行每行两个数x,y,表示在(x,y)处有一头牛。

Output

总共n行,每行一个数ans,第i个数表示第i头牛能到ans个花。

Sample Input

4
2 2 8 4
1 9 4 10
6 7 9 9
3 3 7 3
9
3 4
8 4
11 5
10 7
10 8
9 8
2 8
4 11
9 11
8
1 1
5 10
6 9
3 7
7 1
4 2
7 5
3 3

Sample Output

5
1
0
1
3
1
3
0

HINT

0<=f<=200000
0<=m<=200000
1<=n<=200000

试题分析

神题毒瘤题二合一系列
我们首先可以列出一个很暴力的转移方程:\(f_{i,j}\)表示从\((i,j)\)出发可以到达多少个花。
然后讨论许许多多的情况并转移。复杂度:\(O((n+m+f)^2)\)
这种东西显然数点容斥做不了,可以被特殊数据卡掉。
那么就是数据结构优化\(dp\)喽,但单看转移方程并没有办法优化。
通常在这种情况下我们有两类手段:

  • 差分
  • 前缀和优化
    这怎么看也不想前缀和优化啊,差分显然更靠谱。
    由于是右下角,所以注意扫描线从右到左扫描。
    怎么差分呢?我们不妨设\(g{i,j}=f_{i,j}-f_{i+1,j}\),也就是当前行i比它下面一个的行i-1可以多多少花。

那么更形象一点来说就是它可以走到多少从(i+1,j)走不到的花。
这样的话遇见一朵花就单点+1即可。
如果我们遇到了一个新的区间怎么办呢?
可以发现,最左上角的蓝色格子以及上面(假设还有格子)的若干格子都还可以走到红色部分,而新增矩形下方的从来就不可以走到。
所以\((x_l-1,y)\)要加上红色部分+黑色部分的区间和,++因为当询问矩形上面的点时,我们需要走到右下去++,并且把黄色区间置零。
注意我们是从上往下扫的,所以如果黄色区间中有花就还可以加上。
删除一个区间怎么办呢?
首先还是区间置0(竖着的浅绿色区间),因为两两之间都一样了。
还要考虑左上角的格子(5,6),这个格子照样有向右走的“特权”,所以在这一点上不用变动。
但是这里有一个非常关键的地方:注意黑色格子,这个格子会被向右计算一遍,并且会被向下计算一遍,所以要减一遍,我们可以在区间加入的时候把这个答案先询问好。
查询的话显然就是从奶牛到它下面的第一个栅栏的区间和。

代码暂时咕咕咕。。。

猜你喜欢

转载自www.cnblogs.com/wxjor/p/9643234.html