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的余数。

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 }

 

posted @ 2017-06-13 23:53 chenyushuo 阅读(...) 评论(...) 编辑 收藏