HDU:3333 Turing Tree (树状数组+离线处理+哈希+贪心)
来源:互联网 发布:java身份证识别 编辑:程序博客网 时间:2024/04/28 04:33
题意:给一个数组,每次查询输出区间内不重复数字的和。
思路:
用前缀和的思想可以轻易求得区间的和,但是对于重复数字这点很难处理。在线很难下手,考虑离线处理。
将所有查询区间从右端点由小到大排序,遍历数组中的每个数字,每次将该数字上次出现位置的值在树状数组中改为0,再记录当前位置,在树状数组中修改为当前的数值。这样可以保证在接下来的查询中该数字只出现了一次。这是贪心的思想,只保留最可能被以后区间查询的位置。如果当前位置是某个查询区间的右端点,这时候就可以查询了。最后再根据查询区间的编号排序输出即可了。
注意树状数组查询0位置会出现死循环。
HDU上long long 需要使用I64d。
#include <iostream>#include <cstdio>#include <cstring>#include <vector>#include <map>#include <algorithm>#define ll long long#define MAXN 100005using namespace std;int n;map<int,int> pos;struct Segment{ int num,left,right; ll ans; Segment(int a=0,int b=0,int c=0):num(a),left(b),right(c) { ans=0; } bool operator <(const Segment &p) const { return right<p.right; }};bool cmp(Segment a,Segment b){ return a.num<b.num;}struct BIT{ ll dat[MAXN]; int lowbit(int x) { return -x&x; } void clear() { memset(dat,0,sizeof(dat)); } void add(int x,ll val) { while(x<=n) { dat[x]+=val; x+=lowbit(x); } } ll sum(int x) { ll s=0; while(x>0) { s+=dat[x]; x-=lowbit(x); } return s; } void modify(int x,ll val) { if(x==0) return ; ll t=sum(x)-sum(x-1); add(x,-t+val); }};int arr[MAXN];vector<Segment> vec;BIT tree;int main(){ int T; scanf("%d",&T); while(T--) { scanf("%d",&n); pos.clear(); for(int i=1; i<=n; ++i) scanf("%d",&arr[i]); int q; scanf("%d",&q); vec.clear(); for(int i=1; i<=q; ++i) { int x,y; scanf("%d%d",&x,&y); vec.push_back(Segment (i,x,y)); } sort(vec.begin(),vec.end()); tree.clear(); for(int i=1,j=0; i<=n&&j<vec.size(); ++i) { tree.modify(pos[arr[i]],0); tree.modify(i,arr[i]); pos[arr[i]]=i; while(j<vec.size()&&i==vec[j].right) { vec[j].ans=tree.sum(vec[j].right)-tree.sum(vec[j].left-1); j++; } } sort(vec.begin(),vec.end(),cmp); for(int i=0; i<vec.size(); ++i) printf("%I64d\n",vec[i].ans); } return 0;}
0 0
- HDU:3333 Turing Tree (树状数组+离线处理+哈希+贪心)
- HDU 3333 Turing Tree(树状数组离线处理)
- HDU 3333 Turing Tree --树状数组+离线处理
- HDU 3333 Turing Tree (离线树状数组)
- HDU 3333 Turing Tree 树状数组离线
- hdu 3333 Turing Tree(树状数组离线操作)
- HDU 3333 Turing Tree (离散化+离线处理+树状数组)
- HDU-3333-Turing Tree(离线+哈希+树状数组|线段树)
- HDU 3333 Turing Tree(树状数组)
- hdu 3333 Turing Tree ( 树状数组)
- hdu 3333 Turing Tree 树状数组
- HDU - 3333 Turing Tree(树状数组)
- HDU 3333 Turing Tree(离线操作+线段树||树状数组)
- 【HDU 3333】【离线询问 树状数组 前驱思想】Turing Tree【 求区间中不同的数的和】
- HDU 3333 Turing Tree 线段树 or 树状数组
- hdu 3333 Turing Tree 线段树/树状数组
- hdu 3333 Turing Tree 树状数组或者线段树
- HDU 3333 Turing Tree(树状数组 || 线段树)
- 实现键盘记录的e.Whick和keyCode
- Java的HashMap和HashTable
- swift语言-隐式解析可选
- java学习笔记
- Android 广播接收器BroadcastReceiver
- HDU:3333 Turing Tree (树状数组+离线处理+哈希+贪心)
- 通过实例来学习使用Linux KVM
- Struts2.3.14路由分析
- 安卓学习第二十二天:ProgressBar与SeekBar与RatingBar
- POJ2653——Pick-up sticks
- 字符串匹配的KMP算法
- 在servlet中通过servletcontext对象读取资源文件的模板代码
- 11g新特性:A useful View V$DIAG_INFO
- 2012年写的万年历