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. String类的equals是如何进行字符串比较的

    先看一段代码: public static void main(String[] args) { String a = new String("abc"); String b = ...

  2. CWMP开源代码研究3——ACS介绍

    声明:本文涉及的开源程序代码学习和研究,严禁用于商业目的. 如有任何问题,欢迎和我交流.(企鹅号:408797506) 本文介绍自己用过的ACS,其中包括开源版(提供下载包)和商业版(仅提供安装包下载 ...

  3. ReactNative新手学习之路06滚动更新ListView数据的小示例

    本节带领大家学习使用ListView 做一个常用的滚动更新数据示例: 知识点: initialListSize={200} 第一次加载多少数据行 onEndReached={this.onEndRea ...

  4. css 隔行变色,表单布局

    隔行变色: #list1 li:nth-of-type(odd){ background:#00ccff;}奇数行  #list1 li:nth-of-type(even){ background:# ...

  5. 用于制作app store的截图的工具:Brief Wrapper —— 最便捷的应用商店屏幕快照

    https://itunes.apple.com/cn/app/brief-wrapper-zui-bian-jie/id991730319?l=en&mt=8 可以快捷的做出类似于下面的这种 ...

  6. SQLite剖析之锁和并发控制

    在SQLite中,锁和并发控制机制都是由pager.c模块负责处理的,用于实现ACID(Atomic.Consistent.Isolated和Durable)特性.在含有数据修改的事务中,该模块将确保 ...

  7. C#接口和抽象类的区别

    大家都容易把这两者搞混,我也一样,在听李建忠老师的设计模式时,他也老把抽象类说成接口,弄的我就更糊涂了,所以找了些网上的资料.      一.抽象类:      抽象类是特殊的类,只是不能被实例化:除 ...

  8. ARC下OC对象和CF对象之间的桥接(bridge)

    在开发iOS应用程序时我们有时会用到Core Foundation对象简称CF,例如Core Graphics.Core Text,并且我们可能需要将CF对象和OC对象进行互相转化,我们知道,ARC环 ...

  9. 设置 github 帐号user.name和邮箱user.email

    git config --global user.name username git config --global user.email username@email.com

  10. PHPstorm的数据库功能

    PHPstorm真是神器,居然有表.视图.存储过程的功能,非常人性化,建表那叫一个舒服,而且sql语句可以像其他代码一样显示"区域",结构更加清晰.