HDU 3333:http://acm.hdu.edu.cn/showproblem.php?pid=3333

这两个题是类似的,都是离线处理查询,对每次查询的区间的右端点进行排序。这里我们需要离散化处理一下,标记一下前面是否出现过这个值,然后不断更新last数组(该数组保存的是每个数最后一次出现的位置)。最后用树状数组维护。

 #include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn = ;
const int maxq = ;
struct node{
int l,r,index;
};
node query[maxq];
ll sum[maxn],ans[maxq];
ll a[maxn],b[maxn],last[maxn];
int n;
bool cmp(node a,node b){
return a.r < b.r;
}
ll getsum(int i){
ll s = ;
while(i > ){
s += sum[i];
i -= i&(-i);
}
return s;
}
void add(int i,ll x){
while(i <= n){
sum[i] += x;
i += i&(-i);
}
}
int main(){
int t;
scanf("%d",&t);
while(t--){
scanf("%d",&n);
for(int i = ;i<=n;i++){
scanf("%I64d",&a[i]);
b[i] = a[i];//离散化用
}
sort(b+,b++n);//排序,以每个数的下标标记
int q;
scanf("%d",&q);
for(int i = ;i<=q;i++){
scanf("%d%d",&query[i].l,&query[i].r);
query[i].index = i;
}
sort(query+,query++q,cmp);
memset(sum,,sizeof(sum));
memset(last,,sizeof(last));
int cnt = ;//每个查询的下标
for(int i = ;i<=n;i++){
int index = lower_bound(b+,b++n,a[i])-b-;//找到该数对应的下标
if(last[index])//判断该数是否出现过,有的话减去
add(last[index],-a[i]);
add(i,a[i]);
last[index] = i;
while(query[cnt].r==i && cnt<=q){
ans[query[cnt].index] = getsum(query[cnt].r)-getsum(query[cnt].l-);
cnt++;
}
}
for(int i = ;i<=q;i++)
printf("%I64d\n",ans[i]);
}
return ;
}

Codeforces 703D:http://codeforces.com/contest/703/problem/D

这道题需要多思考的一步是,要求的区间内出现偶数次的数的异或和,等于这个区间内所有数字的异或和异或这个区间内不同数字的异或和,以1、2、1、3、3、2、3举例,结果就是(1^2^1^3^3^2^3)^(1^2^3),原理就是出现偶数次的数异或它自己等于它本身,出现奇数次的数异或它自己为0。对于区间的异或和,我们可以用数组很方便的求出,不同数字的异或和,只需要对上题进行一下改造就好了。

 #include<bits/stdc++.h>
using namespace std;
typedef long long ll; const int maxn = ;
struct node{
int l,r,index;
};
node query[maxn];
ll sum[maxn],a[maxn],b[maxn],c[maxn],last[maxn],ans[maxn];
int n;
bool cmp(node a,node b){
return a.r < b.r;
}
ll getsum(int i){
ll s = ;
while(i > ){
s ^= sum[i];//注意
i -= i&(-i);
}
return s;
}
void add(int i,ll x){
while(i <= n){
sum[i] ^= x;//注意
i += i&(-i);
}
}
int main(){
scanf("%d",&n);
for(int i = ;i<=n;i++){
scanf("%I64d",&a[i]);
c[i] = a[i]^c[i-];//求前缀异或和
b[i] = a[i];
}
sort(b+,b++n);
int q;
scanf("%d",&q);
for(int i = ;i<=q;i++){
scanf("%d%d",&query[i].l,&query[i].r);
query[i].index = i;
}
sort(query+,query++q,cmp);
int cnt = ;
for(int i = ;i<=n;i++){
int index = lower_bound(b+,b++n,a[i])-b-;
if(last[index])
add(last[index],a[i]);
last[index] = i;
add(i,a[i]);
while(query[cnt].r==i && cnt<=q){
ans[query[cnt].index] = (c[query[cnt].r]^c[query[cnt].l-])^(getsum(query[cnt].r)^getsum(query[cnt].l-));//注意
cnt++;
}
}
for(int i = ;i<=q;i++)
printf("%I64d\n",ans[i]);
return ;
}

HDU 3333 | Codeforces 703D 树状数组、离散化的更多相关文章

  1. HDU 3333 Turing Tree (树状数组)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3333 题意就是询问区间不同数字的和. 比较经典的树状数组应用. //#pragma comment(l ...

  2. HDU 4325 Flowers(树状数组+离散化)

    http://acm.hdu.edu.cn/showproblem.php?pid=4325 题意:给出n个区间和m个询问,每个询问为一个x,问有多少个区间包含了x. 思路: 因为数据量比较多,所以需 ...

  3. HDU 3333 - Turing Tree (树状数组+离线处理+哈希+贪心)

    题意:给一个数组,每次查询输出区间内不重复数字的和. 这是3xian教主的题. 用前缀和的思想可以轻易求得区间的和,但是对于重复数字这点很难处理.在线很难下手,考虑离线处理. 将所有查询区间从右端点由 ...

  4. HDU 3333 Turing Tree --树状数组+离线处理

    题意:统计一段序列[L,R]的和,重复元素只算一次. 解法:容易看出在线做很难处理重复的情况,干脆全部讲查询读进来,然后将查询根据右端点排个序,然后离散化数据以后就可以操作了. 每次读入一个数,如果这 ...

  5. hdu4605 树状数组+离散化+dfs

    Magic Ball Game Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) ...

  6. BZOJ_5055_膜法师_树状数组+离散化

    BZOJ_5055_膜法师_树状数组+离散化 Description 在经历过1e9次大型战争后的宇宙中现在还剩下n个完美维度, 现在来自多元宇宙的膜法师,想偷取其中的三个维度为伟大的长者续秒, 显然 ...

  7. POJ 2299 【树状数组 离散化】

    题目链接:POJ 2299 Ultra-QuickSort Description In this problem, you have to analyze a particular sorting ...

  8. Educational Codeforces Round 10 D. Nested Segments 离线树状数组 离散化

    D. Nested Segments 题目连接: http://www.codeforces.com/contest/652/problem/D Description You are given n ...

  9. HDU 4325 Flowers 树状数组+离散化

    Flowers Problem Description As is known to all, the blooming time and duration varies between differ ...

随机推荐

  1. 洛谷10月月赛Round.3

    Rank11:260=60+100+100 P2409 Y的积木 题目背景 Y是个大建筑师,他总能用最简单的积木拼出最有创意的造型. 题目描述 Y手上有n盒积木,每个积木有个重量.现在他想从每盒积木中 ...

  2. [tem]RMQ(st)

    倍增思想 代码中有两个测试 #include <iostream> #include <cmath> using namespace std; const int N=1e5; ...

  3. poj[1187][Noi 01]陨石的秘密

    Description 公元11380年,一颗巨大的陨石坠落在南极.于是,灾难降临了,地球上出现了一系列反常的现象.当人们焦急万分的时候,一支中国科学家组成的南极考察队赶到了出事地点.经过一番侦察,科 ...

  4. 3172: [Tjoi2013]单词

    3172: [Tjoi2013]单词 Time Limit: 10 Sec  Memory Limit: 512 MBSubmit: 3246  Solved: 1565[Submit][Status ...

  5. 当Table中td内容为空时,显示边框的办法

    1. 在 table的css里面加: border-collapse:collapse;在 td 的css里面加: empty-cells:show; 2 .最简单的就是 在TD里写个    说明: ...

  6. javascript马赛克遮罩图片切换效果:XMosaic.js(转)

    新鲜出炉的javascript图片切换特效,实现的是马赛克遮罩切换.在flash里,好实现遮罩动画很简单,不过JS实现起来就有些困难了. XMosaic.js,与XScroll.js和XScroll2 ...

  7. 20145233 2016-2017 1 linux题目总结

    20145233 2016-2017 1 linux题目总结 第一周考试知识汇总 判断:实验楼环境中所有的默认系统用户名和密码均为 shiyanlou.(x ). 填空:Linux Bash中,Ctr ...

  8. 对.net技术组件的分析和选择

    .net很庞杂,学习最忌讳什么?为了学而学,而不是为了用而学.我们不是为了成为教师,所以不要成为书呆子,不要成为"博士",要从庞杂的技术群中选择自己需要的内容进行学习. 如果不加选 ...

  9. 创建django项目

    python /usr/local/lib/python3.4/dist-packages/Django-1.9.10-py3.4.egg/django/bin/django-admin.py sta ...

  10. struts2报错:There is no Action mapped for namespace [/] and action name [userAction!add]

    使用struts2.3进行动态方法调用时出现: There is no Action mapped for namespace [/user] and action name [user!add] a ...