hdu3874 Necklace 线段树端点更新
来源:互联网 发布:易语言手机版远控源码 编辑:程序博客网 时间:2024/04/30 08:27
题目大意:给n个数,求任意区间不相同数字之和。
题目分析:n个数是给定的,不会变了,区间也是给定的。由于要求任意区间不重复数字之和,那就和这道super mario非常类似了,我们可以离线处理所有询问。由于要求不重复数字之和,我们把询问区间按右断点排序,这样从左往右扫描数列,如果以前没有出现的数字,直接插入,如果出现了,将这个数字上次出现的位置删去,在当前位置重新插入这个数。如果扫描的位置大于当前要查询的区间右端点,处理询问。由于所有要查询区间已按右端点排序,所以我们保证所有重复的数字也在靠右的地方插入,而每个重复的数字只插入了一次,所以可以保证所求区间数字和不重复。由于给定数字不超过1000000,所以直接开大数组搞,如果数字再大的话,就要哈希了。我的线段树跑了3000ms+,由于这题只要求区间和,所以BIT才是更好的选择,看了一下ranklist,好像都在1000ms+,说明这题的后台暑假还算给力啊哈哈。
#include <iostream>#include <cstring>#include <cstdio>#include <algorithm>#include <cmath>using namespace std;#define maxn 60000#define ll long longconst int N = 1000005;int hash[N];int save[N];ll tree[maxn<<2];struct node{ int l,r,id;}ask[maxn<<2];ll ans[maxn<<2];bool cmp(node aa,node bb){ if(aa.r != bb.r) return aa.r < bb.r; else return aa.l < bb.l;}void pushup(int rt){ tree[rt]=tree[rt<<1]+tree[rt<<1|1];}void update(int rt,int l,int r,int x,int val){ if(l==r) { tree[rt]+=val; return; } int m=(l+r)>>1; if(x<=m) { update(rt<<1 , l , m , x , val); } else { update(rt<<1|1 , m+1 , r , x , val); } pushup(rt);}ll query(int rt,int l,int r,int x,int y){ if(x==l&&r==y) { return tree[rt]; } int m=(l+r)>>1; if(x>m) return query(rt<<1|1 ,m+1,r,x,y); else if(y<=m) return query(rt<<1,l,m,x,y); else return query(rt<<1 ,l,m,x,m)+query(rt<<1|1,m+1,r,m+1,y);}int main(){ int t,n,m; int a,b; scanf("%d",&t); while(t--) { memset(hash,-1,sizeof(hash)); scanf("%d",&n); for(int i=1;i<=n;i++) scanf("%d",&save[i]); scanf("%d",&m); for(int i=1;i<=m;i++) { scanf("%d%d",&ask[i].l,&ask[i].r); ask[i].id=i; } sort(ask+1,ask+1+m,cmp); memset(tree,0,sizeof(tree)); int j=1; for(int i=1;i<=m;) { if(j<=ask[i].r) { if(hash[save[j]]==-1) { update(1,1,n,j,save[j]); hash[save[j]]=j; } else { update(1,1,n,hash[save[j]],-save[j]); hash[save[j]]=j; update(1,1,n,j,save[j]); } j++; } else { ans[ask[i].id]=query(1,1,n,ask[i].l,ask[i].r); i++; } } for(int i = 1;i <= m;i ++) printf("%I64d\n",ans[i]); } return 0;}
0 0
- hdu3874 Necklace 线段树端点更新
- 线段树 hdu3874 Necklace
- hdu3874 Necklace 线段树/树状数组
- hdu3874-Necklace 线段树+离散化
- hdu3874(线段树点更新)
- [树状数组&线段树]HDU3874 Necklace 离线思想
- hdu3874 线段树单点更新+离线处理
- hdu1754 线段树端点更新
- HDU3874:Necklace
- poj2828 Buy Tickets 线段树端点更新
- hdu4417 Super Mario 线段树端点更新
- hdu3874(离线思想+线段树)
- hdu 3874 Necklace 线段树 单点更新
- 【题解】[hdu3874]Necklace
- HDU3874 Necklace[树状数组]
- hdu3874/hdu3333 线段树区间求和
- POJ 2528 区间端点离散化,线段树区间更新
- 线段树 端点更新 hdu-1166-敌兵布阵
- 如何将小米3连接Eclipse
- Python新人技巧
- 附加AdventureWorks过程中的5120/948错误处理方法
- 根据各视频网站网址获取SWF链接的PHP实例仅供参考
- Android开发之Activity之间的相互调用
- hdu3874 Necklace 线段树端点更新
- SUN官方API中文版【JDK1.6】
- tar命令排除.svn .git等目录
- PCA的应用示例
- Step By Step(C++模板Trait)
- An internal error occurred during: "Add Deployment".
- Android带图片的textView
- linux C复习:进程空间组成
- StringBuilder有多消耗性能?