首页 > 代码库 > HDU 4866:Shooting

HDU 4866:Shooting

HDU 4866:Shooting

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4866

题目大意:给出$n$条平行于$x$轴的线段,每次查询给出一个横坐标,求该位置上方的前$k$($k$随询问变化)个线段的高度之和。

主席树

代码如下:

 1 #include <cstdio> 2 #include <algorithm> 3 #include <cmath> 4 #define MAX 200005 5 using namespace std; 6 typedef long long ll; 7 ll n,m,x,p,f[MAX],cnt; 8 struct segment{ 9     ll x,d,f;10     segment(ll X=0,ll D=0,ll F=0){x=X;d=D;f=F;}11     friend bool operator<(segment a,segment b){12         if(a.x==b.x)return abs(a.d)<abs(b.d);13         return a.x<b.x;14     }15 }seg[MAX];16 struct HJT{17     ll root[MAX],cnt;18     struct node{19         ll val,num,L_son,R_son;20     }Tree[MAX<<5];21     void init(){22         root[0]=0;23         cnt=0;24     }25     ll Newnode(ll val,ll num,ll L_son,ll R_son){26         ll idx=++cnt;27         Tree[idx].val=val;28         Tree[idx].num=num;29         Tree[idx].L_son=L_son;30         Tree[idx].R_son=R_son;31         return idx;32     }33     void Insert(ll &root,ll pre_rt,ll L,ll R,ll pos,ll val,ll f){34         root=Newnode(Tree[pre_rt].val+val,Tree[pre_rt].num+f,Tree[pre_rt].L_son,Tree[pre_rt].R_son);35         if(L==R)return;36         ll mid=(L+R)>>1;37         if(pos<=mid)Insert(Tree[root].L_son,Tree[pre_rt].L_son,L,mid,pos,val,f);38         else Insert(Tree[root].R_son,Tree[pre_rt].R_son,mid+1,R,pos,val,f);39     }40     ll Query(ll S,ll L,ll R,ll K){41         if(K==0)return 0;42         if(L==R){43             if(K>=Tree[S].num)return Tree[S].val;44             else return Tree[S].val/Tree[S].num*K;45         }46         ll mid=(L+R)>>1,num=Tree[Tree[S].L_son].num;47         if(K<=num)return Query(Tree[S].L_son,L,mid,K);48         return Tree[Tree[S].L_son].val+Query(Tree[S].R_son,mid+1,R,K-num);49     }50 }gao;51 int main(void){52     while(~scanf("%lld%lld%lld%lld",&n,&m,&x,&p)){53         cnt=0;gao.init();54         for(int i=0;i<n;++i){55             ll l,r,d;56             scanf("%lld%lld%lld",&l,&r,&d);57             seg[2*i]=segment(l,d,1);58             seg[2*i+1]=segment(r+1,-d,-1);59             f[cnt++]=d;60         }61         sort(seg,seg+2*n);62         sort(f,f+cnt);63         cnt=unique(f,f+cnt)-f;64         for(int i=0;i<2*n;++i){65             ll pos=lower_bound(f,f+cnt,abs(seg[i].d))-f;66             gao.Insert(gao.root[i+1],gao.root[i],1,cnt,pos+1,seg[i].d,seg[i].f);67         }68         ll pre=1;69         while(m--){70             ll x,a,b,c,ans,doubled=1,pos;71             scanf("%lld%lld%lld%lld",&x,&a,&b,&c);72             if(pre>p)doubled=2;73             pos=upper_bound(seg,seg+2*n,segment(x+1,0,0))-seg;74             ans=gao.Query(gao.root[pos],1,cnt,(pre%c*a+b)%c);75             pre=doubled*ans;76             printf("%lld\n",pre);77         }78     }79 }

 

HDU 4866:Shooting