bzoj 2161: 布娃娃

来源:互联网 发布:mac可以玩qq堂吗 编辑:程序博客网 时间:2024/04/29 22:31

题意:最难的部分还是不概括了。。
题解:权值线段树或平衡树或pbds
把一个点分成l、r、p三个点,排序扫一遍就好了。
偷懒用了pbds
代码:

#include<bits/stdc++.h>#include<ext/pb_ds/assoc_container.hpp>using namespace std;using namespace __gnu_pbds;int n;struct hh{    long long c;    int p,l,r;}a[100010];struct oo{    int pos,id,type;//l:0 p:1 r:2}b[300010];long long tmp[100010];const long long mod=19921228;tree<long long,null_mapped_type,greater<long long>,rb_tree_tag,tree_order_statistics_node_update>tr;long long ans=0;void in(){    long long add,first,mod,prod;    scanf("%lld%lld%lld%lld",&add,&first,&mod,&prod);    tmp[1]=first%mod;    for(int i=2;i<=n;i++)    tmp[i]=(tmp[i-1]*prod+add+i)%mod;/*    for(int i=1;i<=n;i++)    printf("%lld ",tmp[i]);    puts("");*/}int cmp(oo x,oo y){    return x.pos==y.pos?x.type<y.type:x.pos<y.pos;}int main(){    scanf("%d",&n);    in();    for(int i=1;i<=n;i++)    a[i].p=tmp[i];    in();    for(int i=1;i<=n;i++)    a[i].c=tmp[i];    in();    for(int i=1;i<=n;i++)    a[i].l=tmp[i];    in();    for(int i=1;i<=n;i++)    a[i].r=tmp[i];    for(int i=1;i<=n;i++)    if(a[i].l>a[i].r)    swap(a[i].l,a[i].r);/*    for(int i=1;i<=n;i++)    printf("%d %lld %d %d\n",a[i].p,a[i].c,a[i].l,a[i].r);    puts("");*/    int num=0;    for(int i=1;i<=n;i++)    {        b[++num]={a[i].l,i,0};        b[++num]={a[i].p,i,1};        b[++num]={a[i].r,i,2};    }    sort(b+1,b+1+num,cmp);    for(int i=1;i<=num;i++)    {        if(b[i].type==0)        tr.insert(a[b[i].id].c*200000+b[i].id);        else if(b[i].type==1)        {            if(tr.size()>=b[i].id)            ans=(ans+*tr.find_by_order(b[i].id-1)/200000)%mod;        }        else        tr.erase(a[b[i].id].c*200000+b[i].id);//      printf("%d %d %d %lld\n",b[i].pos,b[i].id,b[i].type,ans);    }    printf("%lld",ans);}