P2184 贪婪大陆

题目背景

面对蚂蚁们的疯狂进攻,小\(FF\)的\(Tower\) \(defence\)宣告失败……人类被蚂蚁们逼到了\(Greed\) \(Island\)上的一个海湾。现在,小\(FF\)的后方是一望无际的大海, 前方是变异了的超级蚂蚁。 小\(FF\)还有大好前程,他可不想命丧于此, 于是他派遣手下最后一批改造\(SCV\)布置地雷以阻挡蚂蚁们的进攻。

题目描述

小\(FF\)最后一道防线是一条长度为\(N\)的战壕, 小\(FF\)拥有无数多种地雷,而SCV每次可以在\([L,R]\)区间埋放同一种不同于之前已经埋放的地雷。 由于情况已经十万火急,小\(FF\)在某些时候可能会询问你在\([L',R']\)区间内有多少种不同的地雷, 他希望你能尽快的给予答复。

输入输出格式

输入格式:

第一行为两个整数\(n\)和\(m\); \(n\)表示防线长度,\(m\)表示\(SCV\)布雷次数及小\(FF\)询问的次数总和。

接下来有\(m\)行, 每行三个整数\(Q\),\(L\),\(R\); 若\(Q\)=1则表示\(SCV\)在\([L,R]\)这段区间布上一种地雷, 若\(Q=2\)则表示小\(FF\)询问当前\([L,R]\)区间总共有多少种地雷。

输出格式:

对于小FF的每次询问,输出一个答案(单独一行),表示当前区间地雷总数。

说明:

对于30%的数据: \(0<=n, m<=1000\);

对于100%的数据:\(0<=n, m<=10^5\).


说两个方法吧

方法一:维护区间和合并区间时多加上的一部分,基于容斥原理,是这位大佬想到的

具体的:

我们维护\(sum\)代表这个区间的种类数,每次区间修改操作即为对二进制所划分的每个区间+1(不是对每个值,是对区间),防止退化我们用一个\(lazy1\)维护

这时候在区间合并的时候就会产生问题,会重复统计。

我们再维护一个值\(mer\)代表这个二进制区间被多少次划分时分开了,则统计答案时即为\(sum[ls]+sum[rs]-mer[ls]\)

这个也是区间操作,同样用一个\(lazy2\)来维护

Code:

  1. #include <cstdio>
  2. #define ls id<<1
  3. #define rs id<<1|1
  4. const int N=100010;
  5. int sum[N<<2],mer[N<<2],lazy1[N<<2],lazy2[N<<2],n,m;
  6. void push_down(int id,int l,int r)
  7. {
  8. if(l!=r)
  9. {
  10. sum[ls]+=lazy1[id];
  11. sum[rs]+=lazy1[id];
  12. mer[ls]+=lazy2[id];
  13. lazy1[ls]+=lazy1[id];
  14. lazy1[rs]+=lazy1[id];
  15. lazy2[ls]+=lazy2[id];
  16. lazy2[rs]+=lazy2[id];
  17. }
  18. lazy1[id]=lazy2[id]=0;
  19. }
  20. void change(int id,int l,int r,int L,int R)
  21. {
  22. if(l==L&&r==R)
  23. {
  24. sum[id]++;
  25. lazy1[id]++;
  26. lazy2[id]++;
  27. return;
  28. }
  29. int Mid=L+R>>1;
  30. if(r<=Mid)
  31. change(ls,l,r,L,Mid);
  32. else if(l>Mid)
  33. change(rs,l,r,Mid+1,r);
  34. else
  35. {
  36. mer[ls]++;
  37. change(ls,l,Mid,L,Mid);
  38. change(rs,Mid+1,r,Mid+1,R);
  39. }
  40. push_down(id,L,R);
  41. sum[id]=sum[ls]+sum[rs]-mer[ls];
  42. }
  43. int query(int id,int l,int r,int L,int R)
  44. {
  45. push_down(id,L,R);
  46. if(l==L&&r==R)
  47. return sum[id];
  48. int Mid=L+R>>1;
  49. if(r<=Mid)
  50. return query(ls,l,r,L,Mid);
  51. else if(l>Mid)
  52. return query(rs,l,r,Mid+1,r);
  53. else
  54. return query(ls,l,Mid,L,Mid)+query(rs,Mid+1,r,Mid+1,R)-mer[ls];
  55. }
  56. int main()
  57. {
  58. scanf("%d%d",&n,&m);
  59. int q,l,r;
  60. for(int i=1;i<=m;i++)
  61. {
  62. scanf("%d%d%d",&q,&l,&r);
  63. if(q==1) change(1,l,r,1,n);
  64. else printf("%d\n",query(1,l,r,1,n));
  65. }
  66. return 0;
  67. }

方法二:维护区间两端进行统计

我们发现,对于一个区间\(1\)~\(i\),\(i\)及其左边的区间的左端点的数量即为答案

对于一个区间\(i\)~\(n\),\(i\)左边的右端点不是它的答案

综合一下,对于一个区间\(l\)$r$,$r$及左边的左端点数量-$l$左边的右端点数量,不就是$l$\(r\)所覆盖的区间数量了吗?

单点修改,我们只需要用两个树状数组维护就行了

Code:

  1. #include <cstdio>
  2. const int N=100010;
  3. int s[2][N],n,m;
  4. int query(int typ,int x)
  5. {
  6. int sum=0;
  7. while(x)
  8. {
  9. sum+=s[typ][x];
  10. x-=x&-x;
  11. }
  12. return sum;
  13. }
  14. void add(int typ,int x)
  15. {
  16. while(x<=n)
  17. {
  18. s[typ][x]+=1;
  19. x+=x&-x;
  20. }
  21. }
  22. int main()
  23. {
  24. scanf("%d%d",&n,&m);
  25. int q,l,r;
  26. for(int i=1;i<=m;i++)
  27. {
  28. scanf("%d%d%d",&q,&l,&r);
  29. if(q==1)
  30. add(0,l),add(1,r);
  31. else
  32. printf("%d\n",query(0,r)-query(1,l-1));
  33. }
  34. return 0;
  35. }

2018.7.12

洛谷 P2184 贪婪大陆 解题报告的更多相关文章

  1. 洛谷P2184 贪婪大陆

    题目背景 面对蚂蚁们的疯狂进攻,小FF的\(Tower\) \(defence\)宣告失败--人类被蚂蚁们逼到了\(Greed\) \(Island\)上的一个海湾.现在,小FF的后方是一望无际的大海 ...

  2. 洛谷 P2184 贪婪大陆

    题面 又是一类比较套路的题呢? 假如我们的地雷都表示成 [l[i],r[i]] ,要求[L,R],那么就相当于要求满足 (l[i]<=R && r[i]>=L)的i的个数. ...

  3. 洛谷P2184——贪婪大陆

    传送门:QAQQAQ 题意:给一个长度为$n$的区间,每次可以进行两种操作: 1.在$[l,r]$这个区间里放置一个和之前种类不同的炸弹 2.查询在$[l,r]$区间内有多少种不同种类的炸弹 思路:第 ...

  4. 洛谷 P1783 海滩防御 解题报告

    P1783 海滩防御 题目描述 WLP同学最近迷上了一款网络联机对战游戏(终于知道为毛JOHNKRAM每天刷洛谷效率那么低了),但是他却为了这个游戏很苦恼,因为他在海边的造船厂和仓库总是被敌方派人偷袭 ...

  5. 洛谷 P4597 序列sequence 解题报告

    P4597 序列sequence 题目背景 原题\(\tt{cf13c}\)数据加强版 题目描述 给定一个序列,每次操作可以把某个数\(+1\)或\(-1\).要求把序列变成非降数列.而且要求修改后的 ...

  6. 洛谷1087 FBI树 解题报告

    洛谷1087 FBI树 本题地址:http://www.luogu.org/problem/show?pid=1087 题目描述 我们可以把由“0”和“1”组成的字符串分为三类:全“0”串称为B串,全 ...

  7. 洛谷 P3349 [ZJOI2016]小星星 解题报告

    P3349 [ZJOI2016]小星星 题目描述 小\(Y\)是一个心灵手巧的女孩子,她喜欢手工制作一些小饰品.她有\(n\)颗小星星,用\(m\)条彩色的细线串了起来,每条细线连着两颗小星星. 有一 ...

  8. 洛谷 P3177 树上染色 解题报告

    P3177 [HAOI2015]树上染色 题目描述 有一棵点数为\(N\)的树,树边有边权.给你一个在\(0\) ~ \(N\)之内的正整数\(K\),你要在这棵树中选择\(K\)个点,将其染成黑色, ...

  9. 洛谷 P4705 玩游戏 解题报告

    P4705 玩游戏 题意:给长为\(n\)的\(\{a_i\}\)和长为\(m\)的\(\{b_i\}\),设 \[ f(x)=\sum_{k\ge 0}\sum_{i=1}^n\sum_{j=1}^ ...

随机推荐

  1. GIT问题(二)——add报错

  2. ubuntu16.04 CUDA, CUDNN 安装

    这次介绍的是使用 tensorflow1.8, cuda9.0, cudnn7.0的版本 https://developer.nvidia.com/cuda-90-download-archive 下 ...

  3. 第三次博客作业JSF

    JSF规格化设计发展史以及为什么得到人们重视 查阅了n多资料但是仍然没找到. 就说一些jsf的优势吧. 优势:    (1)UI组件 (2)事件驱动模式 (3)用户界面到业务逻辑的直接映射 (4)程序 ...

  4. 第二阶段Sprint冲刺会议8

    进展:重新规划主界面,把视频录制暂放到主页面里,先实现功能,视频提醒后期再做.

  5. SqlServer中的dbo是什么意思

    出处:http://andylin02.iteye.com/blog/486296 SqlServer中的dbo是什么意思? DBO是每个数据库的默认用户,具有所有者权限,即DbOwner 通过用DB ...

  6. 个人作业2——APP案例分析

    产品:网易LOFTER(乐乎)   网易LOFTER是网易旗下图片社交APP,产品覆盖web及移动各端. 网易LOFTER社区内汇聚了多领域的品质生活家与生活达人,包含女神.明星.穿搭.文具.旅行.美 ...

  7. 发布.NET Core到IIS

    目录: 支持操作系统 IIS配置 安装.NET Core Windows Server Hosting 部署应用程序 在IIS配置网站 创建一个数据保护注册表项 常见的错误 额外的资源 支持操作系统 ...

  8. Python模块Scrapy导入出错:ImportError: cannot import name xmlrpc_client

    Mac(OS version: OS X Yosemite 10.10.5)上安装Scrapy模块,使用时出现: from six.moves import xmlrpc_client as xmlr ...

  9. poj 1185(状态压缩DP)

    poj  1185(状态压缩DP) 题意:在一个N*M的矩阵中,‘H'表示不能放大炮,’P'表示可以放大炮,大炮能攻击到沿横向左右各两格,沿纵向上下各两格,现在要放尽可能多的大炮使得,大炮之间不能相互 ...

  10. java 常见的异常大集合

    算术异常类:ArithmeticExecption 空指针异常类:NullPointerException 类型强制转换异常:ClassCastException 数组负下标异常:NegativeAr ...