Problem Description
In the shooting game, the player can choose to stand in the position of [1, X] to shoot, you can shoot all the nearest K targets. The value of K may be different on different shootings. There are N targets to shoot, each target occupy
the position of [Li, Ri] , the distance from the starting line is Di(1<=i<=N). Shooting a target can get the bonus points equal to the distance to the starting line. After each shooting targets still exist. Additional, if the previous bonus points is more
than P, then as a reward for the shooting present bonus points doubled(and then check the next one). Player wants to know the bonus points he got in each shot.



 
Input
The input consists several test cases. 

The first line has two integers, N, M, X, P(1<=N, M ,X<=100000, P<=1000000000), N represents the total number of target shooting, M represents the number of shooting.

The next N lines of three integers L, R, D (1<=L<=R<=X, 1<=D<=10000000), occupy the position of [L, R] and the distance from the starting line is D.

The next M lines, each line contains four integers x, a, b, c (1<=x<=X, 0<=a,b<=N, 1<=c<=10000000), and K = ( a * Pre + b ) % c. Pre is the bonus point of previous shooting , and for the first shooting Pre=1. It denotes standing in the position x and the player
can shoot the nearest K targets.
 
Output
Output M lines each corresponds to one integer.
 
Sample Input
4 3 5 8
1 2 6
2 3 3
2 4 7
1 5 2
2 2 1 5
3 1 1 10
4 2 3 7
 
Sample Output
11
10
18
 
Author
FZU
 
Source

思路:按到start line的距离建树,把线段转换成两个点,逐一插入,插入的时候同样的节点能够共享(如pre的左子树跟x的左子树同样则直接让x的左子树的指针仅仅想pre的左子树就可以)。详见代码。

#include <cstdio>
#include <algorithm>
#define LL long long
using namespace std; struct P{
int pos,val,flag; bool operator<(const struct P &p) const
{
if(pos==p.pos)
{
if(val==p.val) return flag<p.flag;
else return val<p.val;
}
else return pos<p.pos;
} }pt[4000000],ts;//把每条线段转换成两个点,flag=1代表起点,falg=-1代表终点 int ls[4000000],rs[4000000],T[200005],vv[100000],cnum[4000000],nodenum;//ls指向左子树,rs指向右子树,T[i]为树i的根,cnum记录当前节点插入的值的个数
LL sum[4000000]; void insert(int s,int e,int val,int flag,int pre,int &x)//在pre的基础上插入一个点,假设插左边则右子树与pre的右子树同样,直接让x的右子树指向
{ //pre的右子树,再新建左子树
x=++nodenum; ls[x]=ls[pre];//先让x的左右子树都指向pre的左右子树
rs[x]=rs[pre]; sum[x]=sum[pre]+flag*vv[val];//求和
cnum[x]=cnum[pre]+flag;//记录该节点插入的值的个数 if(s!=e)
{
int mid=(s+e)>>1; if(val<=mid) insert(s,mid,val,flag,ls[pre],ls[x]);//插左边就在pre左子树的基础上建x的左子树
else insert(mid+1,e,val,flag,rs[pre],rs[x]);//右边同理
}
} LL query(int s,int e,int k,int idx)
{
if(s==e) return k*vv[s];//假设到了叶子节点返回k*距离 int mid=(s+e)>>1; if(cnum[ls[idx]]>k) return query(s,mid,k,ls[idx]);//假设插入左子树的值的个数大于k就在左子树找
else if(cnum[ls[idx]]==k) return sum[ls[idx]];//假设插入左子树的值的个数等于k就直接返回左子树的sum
else return sum[ls[idx]]+query(mid+1,e,k-cnum[ls[idx]],rs[idx]);//假设插入左子树的值的个数小于k就在右子树找(k-左子树插入的个数)
} int main()
{
int n,m,x,p,i,l,r,val,cnt,t;
LL pre,pos,a,b,c,k,ans; while(~scanf("%d%d%d%d",&n,&m,&x,&p))
{
for(i=0;i<n;i++)
{
scanf("%d%d%d",&l,&r,&val); vv[i]=val; pt[i*2].pos=l;
pt[i*2].val=val;
pt[i*2].flag=1; pt[i*2+1].pos=r+1;
pt[i*2+1].val=val;
pt[i*2+1].flag=-1;
} sort(vv,vv+n);
cnt=unique(vv,vv+n)-vv;//把距离反复的去掉 int lxd=0;//当前已经建好的树的数量 for(i=0;i<n*2;i++) pt[i].val=lower_bound(vv,vv+cnt,pt[i].val)-vv;//把距离转化成在vv数组里面的下标 sort(pt,pt+n*2);//按(pos,val,flag)升序排序 T[0]=ls[0]=rs[0]=sum[0]=cnum[0]=nodenum=0; pre=1; for(i=0;i<m;i++)
{
scanf("%I64d%I64d%I64d%I64d",&pos,&a,&b,&c); k=(a*pre+b)%c; ts.pos=pos;
ts.val=cnt; t=upper_bound(pt,pt+n*2,ts)-pt;//找到pos相应的第t棵树 while(lxd<t)//假设第t棵树还没建好就建树一直到建好第t棵树为止
{
insert(1,cnt,pt[lxd].val,pt[lxd].flag,T[lxd],T[lxd+1]);//在第lxd棵树的基础上建第lxd+1棵树
lxd++;
} ans=query(1,cnt,k,T[t]);//在第t棵树上查询 if(pre>p) ans*=2; pre=ans; printf("%I64d\n",ans);
}
}
}

HDU-4866-Shooting(函数式线段树)的更多相关文章

  1. HDU 4866 Shooting(持久化线段树)

    view code//第二道持久化线段树,照着别人的代码慢慢敲,还是有点不理解 #include <iostream> #include <cstdio> #include & ...

  2. HDU 4866 Shooting (主席树)

    题目链接  HDU 4866 题意  给定$n$条线段.每条线段平行$x$轴,离x轴的距离为$D$,覆盖的坐标范围为$[L, R]$.   现在有$m$次射击行动,每一次的射击行动可以描述为在横坐标$ ...

  3. HDU 4866 Shooting 扫描线 + 主席树

    题意: 在二维平面的第一象限有\(n(1 \leq n \leq 10^5)\)条平行于\(x\)轴的线段,接下来有\(m\)次射击\(x \, a \, b \, c\). 每次射击会获得一定的分数 ...

  4. HDU 4866 Shooting(主席树)题解

    题意:在一个射击游戏里面,游戏者可以选择地面上[1,X]的一个点射击,并且可以在这个点垂直向上射击最近的K个目标,每个目标有一个价值,价值等于它到地面的距离.游戏中有N个目标,每个目标从L覆盖到R,距 ...

  5. hdu 5111 树链剖分加函数式线段树

    这题说的是给了两棵树,各有100000 个节点,然后Q个操作Q<=50000; 每个操作L1 R1 L2 R2.因为对于每棵树都有一个与本棵树其他点与众不同的值, 最后问 在树上从L1到R1这条 ...

  6. 学习笔记--函数式线段树(主席树)(动态维护第K极值(树状数组套主席树))

    函数式线段树..资瓷 区间第K极值查询 似乎不过似乎划分树的效率更优于它,但是如果主席树套树状数组后,可以处理动态的第K极值.即资瓷插入删除,划分树则不同- 那么原理也比较易懂: 建造一棵线段树(权值 ...

  7. POJ2104 K-th number 函数式线段树

    很久没打代码了,不知道为什么,昨天考岭南文化之前突然开始思考起这个问题来,这个问题据说有很多种方法,划分树什么的,不过对于我现在这种水平还是用熟悉的线段树做比较好.这到题今年8月份的时候曾经做过,那个 ...

  8. BZOJ 3123 森林(函数式线段树)

    题目链接:http://61.187.179.132/JudgeOnline/problem.php?id=3123 题意: 思路:总的来说,查询区间第K小利用函数式线段树的减法操作.对于两棵树的合并 ...

  9. BZOJ 3207 花神的嘲讽计划Ⅰ(函数式线段树)

    题目链接:http://61.187.179.132/JudgeOnline/problem.php?id=3207 题意:给出一个数列,若干询问.每个询问查询[L,R]区间内是否存在某个长度为K的子 ...

  10. [Usaco2014 Open Gold ]Cow Optics (树状数组+扫描线/函数式线段树)

    这道题一上手就知道怎么做了= = 直接求出原光路和从目标点出发的光路,求这些光路的交点就行了 然后用树状数组+扫描线或函数式线段树就能过了= = 大量的离散+模拟+二分什么的特别恶心,考试的时候是想到 ...

随机推荐

  1. 数据库分页【Limt与Limt..OFFSET 】

    数据起始 SELECT * from xiaoyao_blogs_essay  limit 20 , 15;解释:20是起始位置,15是页容量.因为id是从15开始的 SELECT * from xi ...

  2. Eclipse+EGit的配置注意点, 以及解决Github多个本地仓库之间的冲突

    问题描述 不同本地仓库(e.g. Repo1, Repo2)之间同时修改一个文件时, 出现文件无法merge的情况. 具体表现为, 冲突(红色双向实心箭头)一直存在, 点pull没反应, 点push报 ...

  3. Highchart 改编风力风向图

    基于highchart修改而成的风力风向图 1.替换highchart.js drawpoints方法,替换内容如下: drawPoints: function() { var a, b = this ...

  4. Python2.7.3 学习——第一个程序 Hello Python World

    Hello World 每学一门语言开始的第一程序都是Hello World ,当然了Python也不例外,下面开始我们的Python第一个程序编写: 1,命令行: (1)打开终端,输入python, ...

  5. SQL Server 数据岸问题

    create table t2(x int constraint pk_t2 primary key);go insert into t2(x) values(1),(2),(3),(5),(7),( ...

  6. 转:一个strcpy的问题(很容易做错)

    下面的执行结果是什么? #include<stdio.h> #include<string.h> void main() { "; "; strcpy(d, ...

  7. Web平台开发流程以及规范

    1.js和css的放的位置顺序与加载速度分析 为了让客户先看到效果,必须要先加CSS 如果在先head加载CSS,如果CSS大,会先下载CSS,再渲染HTML标签 如果CSS放在head中,当显示出H ...

  8. UVA - 1103Ancient Messages(dfs)

    UVA - 1103Ancient Messages In order to understand early civilizations, archaeologists often study te ...

  9. java课程设计(计算器)

    JAVA课程 设 计 报 告 1206401-18   瞿杰 一.设计时间 2013年6月 24日-----6月28日 二.设计地点 湖南城市学院实验楼计算机506机房 三.设计目的 1.巩固学习VB ...

  10. 如何优雅的代码编写 AutoLayout

    概述 使用 Objective-C 纯代码编写 AutoLayout,看 AutoLayout 的字面理解就是自动布局,听起来好像蛮屌的样子.说白了就是适配:适应.兼容各种不同的情况,包括不同版本的操 ...