博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Codeforces Round #114 (Div. 1) D. Wizards and Roads 笛卡尔树+树贪心+阅读题
阅读量:6131 次
发布时间:2019-06-21

本文共 4222 字,大约阅读时间需要 14 分钟。

D. Wizards and Roads

题目连接:

Description

In some country live wizards. They love to build cities and roads.

The country used to have k cities, the j-th city (1 ≤ j ≤ k) was located at a point (xj, yj). It was decided to create another n - k cities. And the i-th one (k < i ≤ n) was created at a point with coordinates (xi, yi):

xi = (a·xi - 1 + b) mod (109 + 9)

yi = (c·yi - 1 + d) mod (109 + 9)
Here a, b, c, d are primes. Also, a ≠ c, b ≠ d.

After the construction of all n cities, the wizards have noticed something surprising. It turned out that for every two different cities i and j, xi ≠ xj and yi ≠ yj holds.

The cities are built, it's time to build roads! It was decided to use the most difficult (and, of course, the most powerful) spell for the construction of roads. Using this spell creates a road between the towns of u, v (yu > yv) if and only if for any city w which lies strictly inside the corner at the point u, v (see below), there is a city s that does not lie in the corner, which is located along the x-coordinate strictly between w and u and simultaneously ys > yv.

A corner on the points p2(x2, y2), p1(x1, y1) (y1 < y2) is the set of points (x, y), for which at least one of the two conditions is fulfilled:

min(x1, x2) ≤ x ≤ max(x1, x2) and y ≥ y1

y1 ≤ y ≤ y2 and (x - x2)·(x1 - x2) ≥ 0
The pictures showing two different corners
In order to test the spell, the wizards will apply it to all the cities that lie on the x-coordinate in the interval [L, R]. After the construction of roads the national government wants to choose the maximum number of pairs of cities connected by the road, so that no city occurs in two or more pairs. Your task is for each m offered variants of values L, R to calculate the maximum number of such pairs after the construction of the roads. Please note that the cities that do not lie in the interval [L, R] on the x-coordinate, do not affect the construction of roads in any way.

Input

The first line contains two space-separated integers n, k (1 ≤ k ≤ n ≤ 105, k ≤ 30). Next k lines contain coordinates of the cities' location points from the first to the k-th one. The j-th line contains space-separated pair of integers xj, yj (0 ≤ xj, yj < 109 + 9) — coordinates of the j-th city.

The next line contains space-separated integers a, b, c, d (2 ≤ a, b, c, d < 109 + 9). It is guaranteed that those numbers are prime and also that a ≠ c, b ≠ d.

It's guaranteed, that for every two different cities i and j, xi ≠ xj and yi ≠ yj holds.

The next line contains integer m (1 ≤ m ≤ 105) — the number of variants to build the roads. Next m lines contain pairs of space-separated integers Li, Ri (0 ≤ Li ≤ Ri < 109 + 9) — the variants of choosing the cities to build the roads.

Output

For any pair of numbers Li, Ri print the answer to the problem on a single line. Print the answers for the pairs in the order, in which the pairs are given in the input data.

Sample Input

6 6

0 0
1 1
2 2
3 3
4 4
5 5
2 3 3 2
4
0 5
1 4
2 3
3 3

Sample Output

3

2
1
0

Hint

题意

平面上给你n个点,保证数据随机

然后有一个定义叫做拐角的东西,就是题目中的图片显示的那个

现在如果某两个点u,v(假设uy>vy)构成的拐角中的任何一个点w,都存在一个能与w形成拐角的点s满足sx在w,v之间,且sy>vy

那么uv就可以连边

现在问你横坐标在l,r区间的点做二分图匹配的最大值是多少

题解:

那个神TM的题意,真是迷

经过猜测,观察,迷之领悟,知道了这么一个结论

假设我们把每个点的下方分成左下角和右下角两个区域,那么每个点只能和这两个区域中的y坐标最大值连边

然后这样递归下来,显然就能够构成一个笛卡尔树的样子(其实就是

然后这是一颗二叉树

所以询问就很简单了,由于是二叉树,所以就是一个简单的贪心(或者dp

然后均摊的直接像线段树那样去跑一发就好了

复杂度是nlogn的

代码

#include
using namespace std;const int maxn = 1e5+7;const int mod = 1e9+9;int n,k,a,b,c,d;pair
p[maxn];int tot=1;struct Tr{ int l,r,x,lson,rson; pair
v;}tree[maxn];int newnode(int &x){ return x=++tot;}pair
deal(pair
a,pair
b){ return make_pair(a.second+b.second,max(a.first+b.second,a.second+b.first)+1);}void build_tree(int l,int r,int x){ int high=-1,id=l; for(int i=l;i<=r;i++) if(p[i].second>high) high=p[i].second,id=i; tree[x].l=p[l].first,tree[x].r=p[r].first,tree[x].x=p[id].first; if(id>l)build_tree(l,id-1,newnode(tree[x].lson)); if(id
query(int l,int r,int x){ if(x==0||l>tree[x].r||r
=tree[x].r)return tree[x].v; if(r
tree[x].x)return query(l,r,tree[x].rson); return deal(query(l,r,tree[x].lson),query(l,r,tree[x].rson));}int main(){ scanf("%d%d",&n,&k); for(int i=0;i

转载地址:http://pkaua.baihongyu.com/

你可能感兴趣的文章
对软件测试团队“核心价值”的思考
查看>>
【算法题】任务分配问题---匈牙利算法
查看>>
memcached配置 启动
查看>>
杂谈:大容量(T级容量)的网盘的意义
查看>>
mysql hash 和 b-tree索引区别和适用范围
查看>>
浅谈Android五大布局(一)——LinearLayout、FrameLayout和AbsoulteLayout
查看>>
一致性hash和solr千万级数据分布式搜索引擎中的应用
查看>>
对ARM9哈佛结构的认识
查看>>
体验VisualStudio 2013中的内存分析功能
查看>>
把一个IEEE754浮点数转换为IBM370浮点数的C#代码
查看>>
Telerik_2012_Q3 RadGrid 汉化
查看>>
高清精美壁纸:2013年11月桌面日历壁纸免费下载
查看>>
函数声明后面的const用法
查看>>
JavaWeb 服务启动时,在后台启动加载一个线程
查看>>
Oracle Form 特殊的默认值 $$variables$$
查看>>
Linux下进程的创建
查看>>
JAX-WS(二)之使用wsimport创建WebService客户端
查看>>
在VC++中使用Tab Control控件
查看>>
c++中智能输出文件
查看>>
【linux】xrander/cvt自定义分辨率
查看>>