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

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

  1. #include<bits/stdc++.h>
  2. using namespace std;
  3. typedef long long ll;
  4. const int maxn = ;
  5. const int maxq = ;
  6. struct node{
  7. int l,r,index;
  8. };
  9. node query[maxq];
  10. ll sum[maxn],ans[maxq];
  11. ll a[maxn],b[maxn],last[maxn];
  12. int n;
  13. bool cmp(node a,node b){
  14. return a.r < b.r;
  15. }
  16. ll getsum(int i){
  17. ll s = ;
  18. while(i > ){
  19. s += sum[i];
  20. i -= i&(-i);
  21. }
  22. return s;
  23. }
  24. void add(int i,ll x){
  25. while(i <= n){
  26. sum[i] += x;
  27. i += i&(-i);
  28. }
  29. }
  30. int main(){
  31. int t;
  32. scanf("%d",&t);
  33. while(t--){
  34. scanf("%d",&n);
  35. for(int i = ;i<=n;i++){
  36. scanf("%I64d",&a[i]);
  37. b[i] = a[i];//离散化用
  38. }
  39. sort(b+,b++n);//排序,以每个数的下标标记
  40. int q;
  41. scanf("%d",&q);
  42. for(int i = ;i<=q;i++){
  43. scanf("%d%d",&query[i].l,&query[i].r);
  44. query[i].index = i;
  45. }
  46. sort(query+,query++q,cmp);
  47. memset(sum,,sizeof(sum));
  48. memset(last,,sizeof(last));
  49. int cnt = ;//每个查询的下标
  50. for(int i = ;i<=n;i++){
  51. int index = lower_bound(b+,b++n,a[i])-b-;//找到该数对应的下标
  52. if(last[index])//判断该数是否出现过,有的话减去
  53. add(last[index],-a[i]);
  54. add(i,a[i]);
  55. last[index] = i;
  56. while(query[cnt].r==i && cnt<=q){
  57. ans[query[cnt].index] = getsum(query[cnt].r)-getsum(query[cnt].l-);
  58. cnt++;
  59. }
  60. }
  61. for(int i = ;i<=q;i++)
  62. printf("%I64d\n",ans[i]);
  63. }
  64. return ;
  65. }

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。对于区间的异或和,我们可以用数组很方便的求出,不同数字的异或和,只需要对上题进行一下改造就好了。

  1. #include<bits/stdc++.h>
  2. using namespace std;
  3. typedef long long ll;
  4.  
  5. const int maxn = ;
  6. struct node{
  7. int l,r,index;
  8. };
  9. node query[maxn];
  10. ll sum[maxn],a[maxn],b[maxn],c[maxn],last[maxn],ans[maxn];
  11. int n;
  12. bool cmp(node a,node b){
  13. return a.r < b.r;
  14. }
  15. ll getsum(int i){
  16. ll s = ;
  17. while(i > ){
  18. s ^= sum[i];//注意
  19. i -= i&(-i);
  20. }
  21. return s;
  22. }
  23. void add(int i,ll x){
  24. while(i <= n){
  25. sum[i] ^= x;//注意
  26. i += i&(-i);
  27. }
  28. }
  29. int main(){
  30. scanf("%d",&n);
  31. for(int i = ;i<=n;i++){
  32. scanf("%I64d",&a[i]);
  33. c[i] = a[i]^c[i-];//求前缀异或和
  34. b[i] = a[i];
  35. }
  36. sort(b+,b++n);
  37. int q;
  38. scanf("%d",&q);
  39. for(int i = ;i<=q;i++){
  40. scanf("%d%d",&query[i].l,&query[i].r);
  41. query[i].index = i;
  42. }
  43. sort(query+,query++q,cmp);
  44. int cnt = ;
  45. for(int i = ;i<=n;i++){
  46. int index = lower_bound(b+,b++n,a[i])-b-;
  47. if(last[index])
  48. add(last[index],a[i]);
  49. last[index] = i;
  50. add(i,a[i]);
  51. while(query[cnt].r==i && cnt<=q){
  52. ans[query[cnt].index] = (c[query[cnt].r]^c[query[cnt].l-])^(getsum(query[cnt].r)^getsum(query[cnt].l-));//注意
  53. cnt++;
  54. }
  55. }
  56. for(int i = ;i<=q;i++)
  57. printf("%I64d\n",ans[i]);
  58. return ;
  59. }

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. oracle连接方式、创建数据库用户、忘记数据库密码、用户锁定

    一.oracle六种连接方式 ①myEclipse中 打开myEclipse,window----show view----Other---输入DB点击DB browser 选中右键New.出现如下页 ...

  2. BZOJ 2286 消耗战 (虚树+树形DP)

    给出一个n节点的无向树,每条边都有一个边权,给出m个询问,每个询问询问ki个点,问切掉一些边后使得这些顶点无法与顶点1连接.最少的边权和是多少.(n<=250000,sigma(ki)<= ...

  3. bzoj 3163: [Heoi2013]Eden的新背包问题

    Description "寄没有地址的信,这样的情绪有种距离,你放着谁的歌曲,是怎样的心心静,能不能说给我听."失忆的Eden总想努力地回忆起过去,然而总是只能清晰地记得那种思念的 ...

  4. HTTPS 原理解析

    一 前言 在说HTTPS之前先说说什么是HTTP,HTTP就是我们平时浏览网页时候使用的一种协议.HTTP协议传输的数据都是未加密的,也就是明文的,因此使用HTTP协议传输隐私信息非常不安全.为了保证 ...

  5. 多说评论系统API调用和本地身份说明(JWT)

    多说评论系统是一个非常好用的第三方评论插件,聚合了大多数的SNS平台账号登录和分享功能,UI也很不错. 作为网站快速接入评论系统,多说是一个比较好的选择,其也提供了一些实用的API去满足定制化需求. ...

  6. RapidJSON 代码剖析(三):Unicode 的编码与解码

    根据 RFC-7159: 8.1 Character Encoding JSON text SHALL be encoded in UTF-8, UTF-16, or UTF-32. The defa ...

  7. oracle 32位导64位

    oracle 32位导64位 SHUTDOWN IMMEDIATE; STARTUP MOUNT; ALTER SYSTEM ENABLE RESTRICTED SESSION; ; ; ALTER ...

  8. centos上如何安装redis?|centos傻瓜式安装redis教程

    本文介绍centos安装redis,请不要安装2.4.3,是有问题的. 首先安装gcc yum -y install gcc yum -y install gcc-c++ yum install ma ...

  9. php 错误

    ini_set('display_errors', '1');error_reporting(E_ALL ^ E_NOTICE);   有时有了其它框架 应该用它的配置,要不然,你改了,它又改回去了: ...

  10. 【转】Maven3把命令行创建的web工程转成Eclipse和IntelliJ Idea的工程

    参考链接:http://blog.sina.com.cn/s/blog_4f925fc30102ed5b.html 大前提:在执行mvn eclipse:eclipse命令之前一定要先存在一个含有po ...