bzoj2161: 布娃娃

Description

小時候的雨蕁很是聽話,是父母眼中的好孩子。在學校是老師的左右手,同窗的好榜樣。後來她成爲艾利斯頓第二
代考神,這和小時候培養的良好素質是分不開的。雨蕁的媽媽也爲有這麼一個懂事的女兒感到高興。一次期末考試
,雨蕁不知道第多少次,再次考了整年級第一名。雨蕁的媽媽看到女兒100分的成績單時,臉上又泛起了幸福的笑
容,做爲獎勵,她給雨蕁買了n個布娃娃。細心的雨蕁發現,第i個布娃娃有一個耐心值P[i]以及一個魅力值C[i],
而且還有可以忍受的耐心值的上限R[i]以及下限L[i]。當一個布娃娃j知足L[j]<=P[i]而且P[i]<=R[j],那麼布娃
娃j喜歡布娃娃i。雨蕁還發現,一個布娃娃有可能喜歡它本身。每一個布娃娃心中都有一個謎團,具體來講就是:第
i個布娃娃想知道喜歡它的布娃娃中,魅力值第i大的布娃娃的魅力值是多少,而且稱這個布娃娃的謎團答案爲這個
魅力值的大小,若是不存在,那麼這個布娃娃的謎團答案爲0。鑑於雨蕁的上司棟棟不讓題目的數據過大,下面給
出數據的生成方法:給出16個參數:
Padd, Pfirst, Pmod, Pprod, Cadd, Cfirst, Cmod, Cprod, Ladd, Lfirst, Lmod, Lprod, Radd, Rfirst, Rmod, Rprod。
----------------------------------------------------------------------------------------
P[1] = Pfirst % Pmod, P[i] = (P[i-1]   Pprod + Padd + i) % Pmod (i > 1)。
----------------------------------------------------------------------------------------
對於C、L、R數組也有相似的獲得方式, %表明取餘運算。注意:L和R數組生成完以後,若是某個布娃娃的忍耐度上
限小於下限,那麼交換它的上限和下限。固然,雨蕁也不會讓你告訴她每一個布娃娃的謎團答案,由於那樣會使輸出
數據很大。因此雨蕁但願你告訴她,全部布娃娃謎團答案的和除以19921228的餘數是多少。

Input

輸入的第一行有一個整數n,表明布娃娃的個數。
輸入的第二行有16個用空格隔開的整數
分別表明Padd,Pfirst,Pmod,Pprod,Cadd,Cfirst,Cmod,Cprod,Ladd,Lfirst,Lmod,Lprod,Radd,Rfirst,Rmod,Rprod。
16個參數均爲1到100,000,000中的整數。
 

Output

輸出一個整數,表明全部布娃娃謎團答案的和除以19921228的餘數。ios

Sample Input

3
2 3 4 3 1 4 5 2 3 6 9 1 1 2 3 4

Sample Output

4
 
題解:
  題意等價於求能覆蓋某個點的全部區間中第K大的值,這個就能夠用掃描線+splay去求
code:
 1 #include<cstdio>
 2 #include<iostream>
 3 #include<cmath>
 4 #include<cstring>
 5 #include<algorithm>
 6 using namespace std;
 7 char ch; bool ok;
 8 void read(int &x){
 9     for (ok=0,ch=getchar();!isdigit(ch);ch=getchar()) if (ch=='-') ok=1;
10     for (x=0;isdigit(ch);x=x*10+ch-'0',ch=getchar());
11     if (ok) x=-x;
12 }
13 const int maxn=100005;
14 const int inf=0x3f3f3f3f;
15 const int MOD=19921228;
16 int add,first,mod,prod,tmp[4][maxn];
17 int n,idx,ans;
18 struct Data{
19     int x,id,op;
20 }list[maxn*3];
21 bool operator<(const Data &a,const Data &b){
22     if (a.x!=b.x) return a.x<b.x;
23     return a.op<b.op;    
24 }
25 struct Splay{
26     #define ls son[x][0]
27     #define rs son[x][1]
28     int root,fa[maxn],son[maxn][2],siz[maxn],val[maxn];
29     void init(){
30         root=n+1,siz[n+1]=2,val[n+1]=inf,son[n+1][1]=n+2;
31         siz[n+2]=1,val[n+2]=-inf,fa[n+2]=n+1;
32     }
33     int which(int x){return son[fa[x]][1]==x;}
34     void updata(int x){siz[x]=siz[ls]+1+siz[rs];}
35     void rotate(int x){
36         int y=fa[x],z=fa[y],d=which(x),dd=which(y);
37         fa[son[x][d^1]]=y,son[y][d]=son[x][d^1],fa[x]=z;
38         if (z) son[z][dd]=x;
39         son[x][d^1]=y,fa[y]=x,updata(y);
40     }
41     void splay(int x){
42         while (fa[x]){
43             if (!fa[fa[x]]) rotate(x);
44             else if (which(fa[x])==which(x)) rotate(fa[x]),rotate(x);
45             else rotate(x),rotate(x);    
46         }
47         updata(x),root=x;
48     }
49     void insert(int x,int v){
50         fa[x]=son[x][0]=son[x][1]=0,siz[x]=1,val[x]=v;
51         int f,t;
52         for (f=t=root;t;f=t,t=son[t][v<val[t]]);
53         fa[x]=f,son[f][v<val[f]]=x,splay(x);    
54     }
55     int find_left(int x){for (;son[x][0];x=son[x][0]);return x;}
56     void _delete(int x){
57         splay(x);
58         int y=find_left(son[x][1]);
59         fa[ls]=fa[rs]=0,splay(y),fa[ls]=y,son[y][0]=ls,updata(y);
60     }
61     int find_kth(int x,int k){
62         if (!x) return 0;
63         if (siz[ls]>=k) return find_kth(ls,k);
64         if (siz[ls]+1==k) return x;
65         return find_kth(rs,k-siz[ls]-1);    
66     }
67     int query(int k){
68         int x=find_kth(root,k+1);
69         if (1<=x&&x<=n) return val[x];
70         return 0;
71     }
72 }T;
73 int main(){
74     read(n);
75     for (int op=0;op<4;op++){
76         read(add),read(first),read(mod),read(prod);
77         tmp[op][1]=first%mod;
78         for (int i=2;i<=n;i++) tmp[op][i]=(1LL*tmp[op][i-1]*prod+add+i)%mod;    
79     }
80     for (int i=1;i<=n;i++) if (tmp[2][i]>tmp[3][i]) swap(tmp[2][i],tmp[3][i]);
81     for (int i=1;i<=n;i++) list[++idx]=(Data){tmp[2][i],i,0};
82     for (int i=1;i<=n;i++) list[++idx]=(Data){tmp[0][i],i,1};
83     for (int i=1;i<=n;i++) list[++idx]=(Data){tmp[3][i],i,2};
84     sort(list+1,list+idx+1),T.init();
85     for (int i=1;i<=idx;i++){
86         int id=list[i].id,op=list[i].op;
87         if (op==0) T.insert(id,tmp[1][id]);
88         else if (op==1) ans+=T.query(id),ans%=MOD;
89         else if (op==2) T._delete(id);
90     }
91     printf("%d\n",ans);
92     return 0;
93 }
相關文章
相關標籤/搜索