hdu 4107 Gangster (离线+打标记+树状数组)
来源:互联网 发布:裴雷网络黄金是真的吗 编辑:程序博客网 时间:2024/05/29 10:11
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4107
题意:给你一个数列,和一种操作,l,r,c,相当于给l,r的这个连续的区间上每个数的值+c,但是有个特殊的条件就是如果如果这个区间上的某个数的值>=P则加上的值为2*c,最后输出区间上每个位置的值。
思路:因为查询只有一次所以可以用离线的方法处理,然后对这样的区间加值感觉有很经典的做法就是打标记(对l的位置打一个c的标记(还需要记录标记发生的时间),对r+1的位置打一个-c的标记(同样也需要记录标记发生的时间)),我们可以对每个节点开一个vector来储存每个节点的标记,再维护一个容器储存当前所含有的标记,然后从第一个点开始来每次先将当前节点的标记全部全部加入容器中,容器中的标记按发生的时间顺序排序,然后对于当前节点将标记一个一个的加起来,当节点的值>=P的时候每次增加的值就变成二倍,当然如果就是这么一个一个加的话,那么跟纯模拟暴力的方法没有什么区别,而树状数组是一个很好的加速这一过程的工具,它的每个位置代表一个时间,这样就能很好的维护时间顺序,然后可以直接二分来找和>=P的最小位置pos,将pos之前的和加一倍上去,将pos之后的和加两倍上去。 就是这样了~~
还有一种线段树的做法,就是维护一个区间最大值和区间最小值,这种做法是在线的,其方法是如果当前区间的最大值<P则全部都加上C,如果当前区间的最小值>=P则全部都加上2*C,就是这个思路了,但是这个方法很容易T的,需要姿势很好才行.
code:
#include <cstdio>#include <cstring>#include <cstdlib>#include <cmath>#include <iostream>#include <algorithm>#include <vector>using namespace std;typedef pair<int,int> pp;typedef long long LL;const int maxn=(1<<18)+10;int bit[maxn];int n,m,P;int sum(int i){ int s=0; while(i>0){ s+=bit[i]; i-=(i&-i); } return s;}void add(int i,int x){ while(i<=m){ bit[i]+=x; i+=(i&-i); }}int getK(int K){ int ans=0,cnt=0; for(int i=18;i>=0;i--){ ans+=(1<<i); if(ans>=m||cnt+bit[ans]>=K) ans-=(1<<i); else cnt+=bit[ans]; } return ans+1;}vector<pp> vv[maxn];int b[maxn];int main(){ int l,r,c; while(scanf("%d%d%d",&n,&m,&P)!=EOF){ for(int i=0;i<=m+5;i++) bit[i]=0; for(int i=0;i<=n;i++) vv[i].clear(); for(int k=1;k<=m;k++){ scanf("%d%d%d",&l,&r,&c); vv[l].push_back(pp(k,c)); vv[r+1].push_back(pp(k,-c)); } for(int i=1;i<=n;i++){ for(int j=0;j<vv[i].size();j++){ add(vv[i][j].first,vv[i][j].second); } int pos=getK(P); b[i]=sum(pos)+2*(sum(m)-sum(pos)); } for(int i=1;i<=n;i++){ printf("%d%c",b[i],i==n? '\n':' '); } } return 0;}
0 0
- hdu 4107 Gangster (离线+打标记+树状数组)
- 51nod 1685 树状数组+打标记
- hdu 4638 (树状数组+离线)
- hdu 4417 离线树状数组
- HDU 3333 树状数组离线
- HDU(3333)树状数组+离线
- HDU(3874)树状数组+离线
- hdu 3333 离线+树状数组
- hdu 4638 离线+树状数组
- hdu 4107 Gangster
- HDU 4107 Gangster
- HDU 4107 Gangster
- HDU-4107-Gangster
- HDU 3874 树状数组 + 离线处理
- hdu 4417 离线树状数组 胡乱搞搞
- HDU 3333 树状数组+离线处理
- hdu 4638 Group (树状数组+离线)
- HDU 4638 Group(离线 + 树状数组)
- 小波变换
- ps aux指令詳解
- 并发新特性—Executor框架与线程池
- IOS应用上传到app store记录
- 我对自己目标的设想
- hdu 4107 Gangster (离线+打标记+树状数组)
- AMBA
- APK扩展文件的使用
- Objective-C NSString 创建初始化的几种方法
- Android资源文件res的使用详解(strings,layout,drawable,arrays等)
- Flex如何得到动态创建的Image尺寸
- View layers and animations
- 关于信号量
- HBase ORM SimpleHBase设计