题目链接:点击查看

题目大意:给出 n 条平行于 x 轴的线段,每条线段都的 [ l , r ] 都位于 [ 1 , X ] 之间,每条线段的高度为 d,也就是距离 x 轴的位置,接下来给出 m 次询问,每次询问给出一个 x 和 k ,问:在点 x 处向上的前 k 个线段的高度之和为多少,如果 k 大于点 x 处的线段总数,那么缺少的线段用最高的线段的高度补上

题目分析:因为题目要求了强制在线,所以不能用线段树+离线来完成,区间 [ 1 , X ] 上的每个点可以通过扫描线的思想,将 n 条线段的属性转换为前缀和的思想,这样每个点都可以独立成为一个前缀和的版本了,所有的版本可以利用主席树来维护,每个版本中维护当前所有线段高度的前缀和,这样每次查询时,只需要查询第 x 个版本的主席树,在内部二分找到 k 的位置,然后返回前缀即可,对于 k 不足的地方,在 l == r 的地方稍微处理一下就可以了

代码:

#include<iostream>
#include<cstdio>
#include<string>
#include<ctime>
#include<cmath>
#include<cstring>
#include<algorithm>
#include<stack>
#include<climits>
#include<queue>
#include<map>
#include<set>
#include<sstream>
#include<cassert>
using namespace std;typedef long long LL;typedef unsigned long long ull;const int inf=0x3f3f3f3f;const int N=1e5+100;vector<int>v,node[N];
/*主席树*/
struct Node
{int l,r,num;LL sum;
}tree[N*50];int cnt,root[N];void init()
{root[0]=0;tree[0].l=tree[0].r=tree[0].sum=tree[0].num=0;cnt=1;
}void update(int pos,int flag,int &k,int l,int r)
{tree[cnt++]=tree[k];k=cnt-1;tree[k].num+=flag;tree[k].sum+=flag*v[pos-1];if(l==r)return;int mid=l+r>>1;if(pos<=mid)update(pos,flag,tree[k].l,l,mid);elseupdate(pos,flag,tree[k].r,mid+1,r);
}LL query(int rt,int k,int l,int r)
{if(l==r)return 1LL*v[l-1]*k;int mid=l+r>>1;int num=tree[tree[rt].l].num;LL sum=tree[tree[rt].l].sum;if(num>=k)return query(tree[rt].l,k,l,mid);elsereturn sum+query(tree[rt].r,k-num,mid+1,r);
}
/*主席树*/
/*离散化*/
void discreate()
{sort(v.begin(),v.end());v.erase(unique(v.begin(),v.end()),v.end());
}int get_id(int x)
{return lower_bound(v.begin(),v.end(),x)-v.begin()+1;
}
/*离散化*/int main()
{
#ifndef ONLINE_JUDGE
//  freopen("input.txt","r",stdin);
//  freopen("output.txt","w",stdout);
#endif
//  ios::sync_with_stdio(false);int n,m,X,P;while(scanf("%d%d%d%d",&n,&m,&X,&P)!=EOF){init(); for(int i=1;i<=X+1;i++)node[i].clear();for(int i=1;i<=n;i++){int l,r,d;scanf("%d%d%d",&l,&r,&d);node[l].push_back(d);node[r+1].push_back(-d);v.push_back(d);}discreate();for(int i=1;i<=X;i++){root[i]=root[i-1];for(auto t:node[i])update(get_id(abs(t)),t<0?-1:1,root[i],1,v.size());}LL pre=1;while(m--){int x,a,b,c;scanf("%d%d%d%d",&x,&a,&b,&c);int k=(pre*a+b)%c;LL ans=query(root[x],k,1,v.size());if(pre>P)ans*=2;printf("%lld\n",ans);pre=ans;}}return 0;
}

HDU - 4866 Shooting(主席树+扫描线)相关推荐

  1. hdu 2665(主席树查询区间k大值)

    先贴我自己写的代码做模板虽然跟原博主没什么两样.(一开始空间开的4*maxn,交到hdu上一直TLE很奇怪) #include<bits/stdc++.h> using namespace ...

  2. hdu 1542 Atlantis (线段树+扫描线)

    http://acm.hdu.edu.cn/showproblem.php?pid=1542 单纯的线段树+扫描线求面积并,需要离散化. code: #include <cstdlib> ...

  3. HDU - 5820 Lights(主席树)

    题目链接:点击查看 题目大意:给出一个 n * m 的矩阵,再给出 N 个点,问其中的任意两个点 ( x1 , y1 ) 与 ( x2 , y2 ) 之间,最短路径为 abs( x1 - x2 ) + ...

  4. HDU - 5790 Prefix(主席树+字典树)

    题目链接:点击查看 题目大意:给出 n 个字符串,再给出 m 次询问,每次询问需要输出区间 [ l , r ] 内的所有字符串有多少个不同的前缀,要求算法强制在线 题目分析:统计字符串的前缀,不难想到 ...

  5. Just $h$-index HDU - 6278(主席树找区间大于等于k的个数)

    The hh-index of an author is the largest hh where he has at least hh papers with citations not less ...

  6. Super Mario HDU - 4417(主席树解决区间数字小于k的个数||线段树+离线)

    Mario is world-famous plumber. His "burly" figure and amazing jumping ability reminded in ...

  7. HDU - 1542 Atlantis(线段树+扫描线)

    题目链接:点击查看 题目大意:给出n个矩形的左下角坐标和右上角坐标,求出其总面积,注意,矩形会重叠,重叠部分只计算一次 题目分析:如果暴力做需要考虑容斥原理,两两矩形组合判断是否重合,十分麻烦而且时间 ...

  8. Sequence II HDU - 5919(主席树)

    Mr. Frog has an integer sequence of length n, which can be denoted as a1,a2,⋯,ana1,a2,⋯,an There are ...

  9. HDU 1828 Picture 线段树 扫描线

    写完后才发现数据是int不是double... //#pragma comment(linker, "/STACK:1024000000,1024000000") #include ...

最新文章

  1. r语言在java中的实现_R语言在现实中的应用
  2. Python做web开发,推荐几个能立马上手的小项目
  3. flex 文字竖排_flex button字竖排展示
  4. java线程暂停与恢复suspend和resume
  5. 程序员吐槽_产品经理吐槽大会,程序员勿入
  6. javaee编程题_在JavaEE中使用CDI的简单面向方面的编程(AOP)
  7. java客户端_Java常用的Http client客户端
  8. python基本命令range_Python的Range()函数(指南)
  9. oracle 数据导入 mysql_oracle数据库导出和oracle导入数据的二种方法(oracle导入导出数据)...
  10. msgpack java lua_使用lua-cmsgpack序列化和反序列化lua对象
  11. pg 日期和时间的运算操作
  12. 换到GitHub 博客了
  13. 程序员面试金典——18.7最长合成字符串
  14. C++中include头文件使用与的区别
  15. TP 打开 显示错误信息
  16. App测试工具大全,收藏这篇就够了
  17. 阿里天猫小镇的实质就是为了圈地!
  18. docker安装_Java EE,Docker和Maven(技术提示#89)
  19. 【Python零基础到入门】Python基础语法篇——数字(Number) 学习 【文末送书】
  20. B站哔哩哔哩21届秋招算法岗笔试 假设货币系统包含面值1元、4元、16元、64元共计4种硬币,以及面值1024元的纸币。现在小明使用1024元的纸币购买了一件价值为N(0<N<=1024)的商品

热门文章

  1. 个性化 服务器运行失败,VirtualBox 运行失败
  2. 组合模式java怎么获取钥匙_java中组合模式详解和使用方法
  3. Pod详解-资源配额
  4. B+树(加强版多路平衡查找树)
  5. 使用Zookeeper实现leader选举-Leader Latch
  6. RocketMQ的发展历史
  7. SpringBootAdmin项目创建
  8. 作品分享_作品分享 | No. 1
  9. caioj 1066 动态规划入门(一维一边推4:护卫队)(分组型dp总结)
  10. 理解 Neutron FWaaS - 每天5分钟玩转 OpenStack(117)