HDU 4866 Shooting 扫描线+主席树
来源:互联网 发布:origin数据表转换矩阵 编辑:程序博客网 时间:2024/06/06 19:21
题意是求x点上面到坐标轴前k小的距离之和。
因为x只有100000所以直接扫x至于线段我们可以用vector分别存线段起点和终点,对于扫到p的时候,把以p为起点的线段加入主席树,把p-1位终点的线段拿出主席树,然后就是简单询问。
#include<cstdio>#include<cstring>#include<algorithm>#include<iostream>#include<vector>using namespace std;const int maxn=100005;int a[maxn],root[maxn],tot;vector<int >g[maxn],g1[maxn];typedef long long LL;struct pi{ LL sum1; int sum; int lson; int rson;}pp[maxn*20*3];struct ppi{ int a,b,x;}pp1[maxn];void build(int cnt,int l,int r){ pp[cnt].sum=0; pp[cnt].sum1=0; if(l==r) return ; pp[cnt].lson=++tot; build(tot,l,(l+r)/2); pp[cnt].rson=++tot; build(tot,(l+r)/2+1,r);}void merg(int qq,int cnt,int n,int p,int k,int k1){ int le,ri,mid; le=1; ri=n; while(le<=ri){ pp[cnt]=pp[qq]; pp[cnt].sum+=k; pp[cnt].sum1+=k1; mid=(le+ri)/2; if(le==ri) return ; if(p<=mid){ pp[cnt].lson=++tot; cnt=tot; qq=pp[qq].lson; ri=mid; } else{ pp[cnt].rson=++tot; cnt=tot; qq=pp[qq].rson; le=mid+1; } }}int query(int cnt,int le,int ri,int l,int r){ if(l>r) return 0; if(le>=l&&ri<=r){ return pp[cnt].sum; } int s=0,mid; mid=(le+ri)/2; if(l<=mid) s+=query(pp[cnt].lson,le,mid,l,r); if(r>mid) s+=query(pp[cnt].rson,mid+1,ri,l,r); return s;}LL query1(int cnt,int le,int ri,int l,int r){ if(l>r) return 0; if(le>=l&&ri<=r) return pp[cnt].sum1; LL s=0; int mid=(le+ri)/2; if(l<=mid) s+=query1(pp[cnt].lson,le,mid,l,r); if(r>mid) s+=query1(pp[cnt].rson,mid+1,ri,l,r); return s;}int get(int cnt,int n,int k){ int le=1,ri=n,mid; int p=query(cnt,1,n,1,n); if(p<k){ k=p; } while(le<=ri){ mid=(le+ri)/2; if(query(cnt,1,n,1,mid)>=k) ri=mid-1; else le=mid+1; } return le;}int main(){ int i,j,n,m,x,ppp,aa,b,c; LL k; while(cin>>n>>m>>x>>ppp){ for(i=1;i<=x+1;i++){ g[i].clear(); g1[i].clear(); } tot=0; root[0]=0; tot++; build(0,1,n); for(i=1;i<=n;i++){ scanf("%d%d%d",&pp1[i].a,&pp1[i].b,&pp1[i].x); g[pp1[i].a].push_back(i); g1[pp1[i].b+1].push_back(i); a[i]=pp1[i].x; } sort(a+1,a+1+n); for(i=1;i<=n;i++){ pp1[i].x=lower_bound(a+1,a+1+n,pp1[i].x)-a; } int q; for(i=1;i<=x;i++){ q=root[i-1]; int p=g[i].size(); for(j=0;j<p;j++){ root[i]=++tot; merg(q,tot,n,pp1[g[i][j]].x,1,a[pp1[g[i][j]].x]); q=root[i]; } int w=g1[i].size(); for(j=0;j<w;j++){ root[i]=++tot; merg(q,tot,n,pp1[g1[i][j]].x,-1,-a[pp1[g1[i][j]].x]); q=root[i]; } if(q==root[i-1]){ root[i]=++tot; pp[root[i]]=pp[root[i-1]]; } } LL pre; pre=1; for(i=0;i<m;i++){ scanf("%d%d%d%d",&x,&aa,&b,&c); k=((LL)aa*pre%c+b)%c; if(k==0){ printf("0\n"); pre=0; continue; } int p=get(root[x],n,k); LL qq; int xx=query(root[x], 1, n,1,p-1); qq=query1(root[x],1,n,1,p-1); qq+=(k-xx)*a[p]; if(pre>ppp) qq=qq*2; printf("%lld\n",qq); pre=qq; } }}
0 0
- HDU 4866 Shooting 扫描线+主席树
- 【HDU】4866 Shooting 主席树
- hdu 4866 Shooting(主席树)
- HDU 4866(Shooting-主席树)
- HDU 4866 Shooting 题解:主席树
- hdu 4866 Shooting(主席树学习第三弹)
- [HDU 5820] Lights (扫描线+主席树)
- HDU-4866-Shooting(函数式线段树)
- hdu 4866 Shooting
- HDU 4866Shooting
- hdu 4866 主席树
- hdu 4348 主席树
- HDU 4417 主席树
- HDU 4417 (主席树)
- hdu 5756(主席树)
- hdu 5919 主席树
- HDU 4605 (主席树)
- HDU 4417 主席树
- 经典算法题每日演练——第四题 最长公共子序列
- 规划主键方案
- 常用JD描述
- Android中shape的使用
- Oracle 删除用户和表空间
- HDU 4866 Shooting 扫描线+主席树
- 高德api 使用疑问
- js中escape()函数和unescape()函数
- 文件流,shareperference,应用分级,handler
- Delphi 的内存操作函数-1,2,3,4
- C语言中#define的用法
- 如何简单快速调试高大上的谷歌浏览器
- 回溯,软件开发过程中的病态。
- eclipse方法代码收缩