[Heoi2013]Segment

Time Limit: 40 Sec  Memory Limit: 256 MB

Description

要求在平面直角座標系下維護兩個操做:
1.在平面上加入一條線段。記第i條被插入的線段的標號爲i。
2.給定一個數k,詢問與直線 x = k相交的線段中,交點最靠上的線段的編號。  
node

Input

 
第一行一個整數n,表示共n 個操做。
接下來n行,每行第一個數爲0或1。
 
若該數爲 0,則後面跟着一個正整數 k,表示詢問與直線 
x = ((k +lastans–1)%39989+1)相交的線段中交點(包括在端點相交的情形)最靠上的線段的編號,其中%表示取餘。若某條線段爲直線的一部分,則視做直線與線段交於該線段y座標最大處。如有多條線段符合要求,輸出編號最小的線段的編號。
若該數爲 1,則後面跟着四個正整數 x0, y0, x 1, y 1,表示插入一條兩個端點爲
((x0+lastans-1)%39989+1,(y0+lastans-1)%10^9+1)和((x
1+lastans-1)%39989+1,(y1+lastans-1)%10^9+1) 的線段。
其中lastans爲上一次詢問的答案。初始時lastans=0。 
 
 
spa

Output

對於每一個 0操做,輸出一行,包含一個正整數,表示交點最靠上的線段的編號。若不存在與直線相交的線段,答案爲0。
3d

Sample Input

6
1 8 5 10 8
1 6 7 2 6
0 2
0 9
1 4 7 6 7
0 5

Sample Output

2
0 3

HINT

對於100%的數據,1 ≤ n ≤ 10^5 , 1 ≤  k, x0, x1 ≤ 39989, 1 ≤ y0 ≤ y1 ≤ 10^9。code

思路

代碼實現

 

 1 #include<cstdio>
 2 const int mod2=1e9;
 3 const int mod1=39989;
 4 const int maxn=4e4+10;
 5 const double eps=1e-9;
 6 inline int max_(int x,int y){return x>y?x:y;}
 7 inline void swap_(int&x,int&y){x^=y,y^=x,x^=y;}
 8 inline int dcmp(double x){return (x>eps)-(x<-eps);}
 9 int n,m=0,lastans=0;
10 int opt,x,x0,y0,x1,y1;
11 int a[maxn],id[maxn];
12 int L,R,idx;
13 double K,B;
14 struct node{
15     int id;
16     double k,b;
17     bool v;
18 }t[maxn<<2];
19 void solve(int k,int l,int r){
20     if(t[k].v==0){
21         t[k].k=K,t[k].b=B;
22         t[k].v=1,t[k].id=idx;
23         return;
24     }
25     double y0,y1,y2,y3;
26     y0=t[k].k*l+t[k].b,y1=K*l+B;
27     y2=t[k].k*r+t[k].b,y3=K*r+B;
28     if(dcmp(y1-y0)>0&&dcmp(y3-y2)>0){
29         if(dcmp(K-t[k].k)==0&&dcmp(B-t[k].b)==0) return;
30         t[k].k=K,t[k].b=B,t[k].id=idx;
31         return;
32     }
33     if(dcmp(y1-y0)<=0&&dcmp(y3-y2)<=0) return;
34     int mid=l+r>>1,ls=k<<1,rs=ls|1;
35     solve(ls,l,mid),solve(rs,mid+1,r);
36 }
37 void ins(int k,int l,int r){
38     if(L<=l&&r<=R){
39         solve(k,l,r);
40         return;
41     }
42     int mid=l+r>>1,ls=k<<1,rs=ls|1;
43     if(L<=mid) ins(ls,l,mid);
44     if(R>mid) ins(rs,mid+1,r);
45 }
46 void ins(int x0,int x1,int y0,int y1,int num){
47     L=x0,R=x1,idx=num;
48     K=(0.0+y1-y0)/(0.0+x1-x0),B=y0-x0*K;
49     ins(1,1,maxn);
50 }
51 int aid;
52 double ans;
53 void query(int k,int l,int r,int x){
54     double y=t[k].k*x+t[k].b;
55     if(dcmp(y-ans)==1||(dcmp(y-ans)==0&&t[k].id<aid)) ans=y,aid=t[k].id;
56     if(l==r) return;
57     int mid=l+r>>1,ls=k<<1,rs=ls|1;
58     if(x<=mid) query(ls,l,mid,x);
59     else query(rs,mid+1,r,x);
60 }
61 int main(){
62     scanf("%d",&n);
63     while(n--){
64         scanf("%d",&opt);
65         if(opt==0){
66             scanf("%d",&x);
67             x=(x+lastans-1)%mod1+1;
68             ans=aid=0;
69             query(1,1,maxn,x);
70             if(ans<a[x]||(ans==a[x]&&id[x]<aid)) aid=id[x];
71             printf("%d\n",lastans=aid);
72         }
73         if(opt==1){
74             scanf("%d%d%d%d",&x0,&y0,&x1,&y1),m++;
75             x0=(x0+lastans-1)%mod1+1,y0=(y0+lastans-1)%mod2+1;
76             x1=(x1+lastans-1)%mod1+1,y1=(y1+lastans-1)%mod2+1;
77             if(x0>x1) swap_(x0,x1),swap_(y0,y1);
78             if(x0==x1){if(max_(y0,y1)>a[x0]) a[x0]=max_(y0,y1),id[x0]=m;}
79             else ins(x0,x1,y0,y1,m);
80         }
81     }
82     return 0;
83 }
本站公眾號
   歡迎關注本站公眾號,獲取更多信息