您的位置:首页 > 其它

bzoj2161布娃娃 线段树

2018-01-18 16:03 204 查看

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

16个参数均为1到100,000,000中的整数。

Solution

第一反应就是大数据结构题,想了想主席树发现不用这么麻烦

与之前做过的一题类似,可以理解成一维的扫描线,把l和r拆成两份离线做,在扫到l的时候在线段树中+1,在扫到r+1的时候在线段树中-1,然后注意查询的优先级要小于修改即可

比较sb的是这道题要求我们找区间第k大,然鹅一开始打成了区间第k小

生成数据的时候两个数相乘会爆int,强制类型转换一下就行了

Code

#include <stdio.h>
#include <string.h>
#include <algorithm>
#define rep(i,st,ed) for (int i=st;i<=ed;++i)
typedef long long ll;
const int MOD=19921228;
const int N=400005;
struct data{int p,c,l,r;}d
;
struct Q{int x,y,v,prio;}q
;
int tmp
,n,cnt_q=0;
int sum[N*5];
void modify(int now,int tl,int tr,int x,int v) {
if (tl==tr) {
sum[now]+=v;
return ;
}
int mid=(tl+tr)>>1;
if (x<=mid) modify(now<<1,tl,mid,x,v);
else modify(now<<1|1,mid+1,tr,x,v);
sum[now]=sum[now<<1]+sum[now<<1|1];
}
int query(int now,int tl,int tr,int k) {
if (tl==tr) return tl;
int tot=sum[now<<1];
int mid=(tl+tr)>>1;
if (tot>=k) return query(now<<1,tl,mid,k);
else return query(now<<1|1,mid+1,tr,k-tot);
}
bool cmp(Q x,Q y) {return x.x<y.x||x.x==y.x&&x.prio>y.prio;}
bool cmp2(int x,int y) {return x>y;}
int main(void) {
scanf("%d",&n);
int add,first,mod,prod;
scanf("%d%d%d%d",&add,&first,&mod,&prod);
d[1].p=first%mod; rep(i,2,n) d[i].p=(ll)((ll)d[i-1].p*prod+add+i)%mod;
scanf("%d%d%d%d",&add,&first,&mod,&prod);
d[1].c=first%mod; rep(i,2,n) d[i].c=(ll)((ll)d[i-1].c*prod+add+i)%mod;
scanf("%d%d%d%d",&add,&first,&mod,&prod);
d[1].l=first%mod; rep(i,2,n) d[i].l=(ll)((ll)d[i-1].l*prod+add+i)%mod;
scanf("%d%d%d%d",&add,&first,&mod,&prod);
d[1].r=first%mod; rep(i,2,n) d[i].r=(ll)((ll)d[i-1].r*prod+add+i)%mod;
rep(i,1,n) if (d[i].l>d[i].r) std:: swap(d[i].l,d[i].r);
rep(i,1,n) tmp[i]=d[i].c;
std:: sort(tmp+1,tmp+n+1); int size=std:: unique(tmp+1,tmp+n+1)-tmp-1;
rep(i,1,n) {
int bobo=std:: lower_bound(tmp+1,tmp+size+1,d[i].c)-tmp;
bobo=size-bobo+1;
q[++cnt_q]=(Q){d[i].l,bobo,1,2};
q[++cnt_q]=(Q){d[i].r+1,bobo,-1,2};
q[++cnt_q]=(Q){d[i].p,0,i,1};
}
std:: sort(q+1,q+cnt_q+1,cmp);
std:: reverse(tmp+1,tmp+size+1);
int ans=0;
rep(i,1,cnt_q) {
if (q[i].prio==2) {
modify(1,1,size,q[i].y,q[i].v);
} else {
if (sum[1]>=q[i].v) ans=(ans+tmp[query(1,1,size,q[i].v)]%MOD)%MOD;
}
}
printf("%d\n", ans);
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: