题目链接:戳我

补一张图

我们尝试把圆上的扇形转化成直线上的矩形——我们维护[1,2m]的区间,那么每个能产生贡献的子区间的长度第K大的半径的平方的总和就是answer了。

怎么转化呢?左端点为a1+m+1,右端点为a2+m。为什么要+m?因为原先的范围是[-m,m]的,所以整体右移。为什么左端点要+1?因为我们维护的是区间,所以这里的每一个下标表示的是以该position为右端点,长度为1的区间。

我们先按照半径长度从大到小排序,如果一个区间覆盖数量超过K个,就不需要再处理了。(优化时间复杂度)

之后就是线段树操作了。我们在更改的同时求出答案。(其实分开写也行,就是要注意因为我们乘上的系数使然,所以区间必须也是当前的修改区间)

minn表示该区间的所有子区间覆盖量的min,maxx是该区间的所有子区间的覆盖量的max。

注意我们的siz是由左右子区间合并而来的。所以产生贡献之后,记得赋值为0,这样就不会对它的父亲区间产生贡献了。

代码如下:

  1. #include<iostream>
  2. #include<cstdio>
  3. #include<cstring>
  4. #include<algorithm>
  5. #include<cmath>
  6. #define MAXN 2000010
  7. using namespace std;
  8. int n,m,k;
  9. long long ans=0;
  10. struct Node{int l,r,c;}node[MAXN];
  11. struct Node2{int l,r,tag,minn,maxx,siz;}t[MAXN<<2];
  12. inline bool cmp(struct Node x,struct Node y){return x.c>y.c;}
  13. inline int ls(int x){return x<<1;}
  14. inline int rs(int x){return x<<1|1;}
  15. inline void push_up(int x)
  16. {
  17. t[x].maxx=max(t[ls(x)].maxx,t[rs(x)].maxx);
  18. t[x].minn=min(t[ls(x)].minn,t[rs(x)].minn);
  19. t[x].siz=t[ls(x)].siz+t[rs(x)].siz;
  20. }
  21. inline void build(int x,int l,int r)
  22. {
  23. t[x].l=l,t[x].r=r;
  24. if(l==r) {t[x].siz=1;return;}
  25. int mid=(l+r)>>1;
  26. build(ls(x),l,mid);
  27. build(rs(x),mid+1,r);
  28. push_up(x);
  29. }
  30. inline void solve(int x,int k)
  31. {
  32. t[x].tag+=k;
  33. t[x].minn+=k;
  34. t[x].maxx+=k;
  35. }
  36. inline void push_down(int x)
  37. {
  38. int l=t[x].l,r=t[x].r;
  39. if(t[x].tag)
  40. {
  41. solve(ls(x),t[x].tag);
  42. solve(rs(x),t[x].tag);
  43. t[x].tag=0;
  44. }
  45. }
  46. inline int update_query(int x,int ll,int rr)
  47. {
  48. int l=t[x].l,r=t[x].r;
  49. if(t[x].minn>=k) return 0;
  50. if(ll<=l&&r<=rr)
  51. {
  52. if(t[x].maxx<k-1) {t[x].minn++,t[x].maxx++,t[x].tag++;return 0;}
  53. if(t[x].minn>=k-1)
  54. {
  55. int cur_ans=t[x].siz;
  56. t[x].siz=0;
  57. t[x].minn++;
  58. return cur_ans;
  59. }
  60. int cur_ans=0;
  61. push_down(x);
  62. cur_ans+=update_query(ls(x),ll,rr);
  63. cur_ans+=update_query(rs(x),ll,rr);
  64. push_up(x);
  65. return cur_ans;
  66. }
  67. push_down(x);
  68. int mid=(l+r)>>1;
  69. int cur_ans=0;
  70. if(ll<=mid) cur_ans+=update_query(ls(x),ll,rr);
  71. if(mid<rr) cur_ans+=update_query(rs(x),ll,rr);
  72. push_up(x);
  73. return cur_ans;
  74. }
  75. int main()
  76. {
  77. #ifndef ONLINE_JUDGE
  78. freopen("ce.in","r",stdin);
  79. #endif
  80. scanf("%d%d%d",&n,&m,&k);
  81. for(int i=1;i<=n;i++)
  82. {
  83. scanf("%d%d%d",&node[i].c,&node[i].l,&node[i].r);
  84. node[i].l+=m+1;
  85. node[i].r+=m;
  86. }
  87. sort(&node[1],&node[n+1],cmp);
  88. build(1,1,m*2);
  89. for(int i=1;i<=n;i++)
  90. {
  91. int cur_ans=0;
  92. if(node[i].l<node[i].r)
  93. cur_ans+=update_query(1,node[i].l,node[i].r);
  94. else if(node[i].l>node[i].r)
  95. {
  96. cur_ans+=update_query(1,node[i].l,m*2);
  97. cur_ans+=update_query(1,1,node[i].r);
  98. }
  99. ans+=1ll*cur_ans*node[i].c*node[i].c;
  100. //printf("i=%d ans=%lld\n",i,ans);
  101. }
  102. printf("%lld\n",ans);
  103. return 0;
  104. }

SHOI2013 扇形面积并的更多相关文章

  1. 【BZOJ4418】[Shoi2013]扇形面积并 扫描线+线段树

    [BZOJ4418][Shoi2013]扇形面积并 Description 给定N个同心的扇形,求有多少面积,被至少K个扇形所覆盖. Input 第一行是三个整数n,m,k.n代表同心扇形的个数,m用 ...

  2. 4418: [Shoi2013]扇形面积并|二分答案|树状数组

    为何感觉SHOI的题好水. ..又是一道SB题 从左到右枚举每个区间,遇到一个扇形的左区间就+1.遇到右区间就-1,然后再树状数组上2分答案,还是不会码log的.. SHOI2013似乎另一道题发牌也 ...

  3. bzoj4418 [Shoi2013]扇形面积并

    传送门:http://www.lydsy.com/JudgeOnline/problem.php?id=4418 [题解] 被题目名称吓死系列. 用一棵线段树维护当前有哪些半径. 那么将扇形差分,每段 ...

  4. SHOI 2013 【扇形面积并】

    早上考的,我打了80分的部分分,出来和同学讨论的时候真想扇自己一巴掌...... 题目描述: 给定 n 个同心的扇形,求有多少面积,被至少k 个扇形所覆盖. 输入输出格式 输入格式: 第一行是三个整数 ...

  5. OI题目类型总结整理

    ## 本蒟蒻的小整理qwq--持续更新(咕咕咕) 数据结构 数据结构 知识点梳理 数据结构--线段树 推荐yyb dalao的总结--戳我 以后维护线段树还是把l,r写到struct里面吧,也别写le ...

  6. bzoj AC倒序

    Search GO 说明:输入题号直接进入相应题目,如需搜索含数字的题目,请在关键词前加单引号 Problem ID Title Source AC Submit Y 1000 A+B Problem ...

  7. 求两圆相交部分面积(C++)

    已知两圆圆心坐标和半径,求相交部分面积: #include <iostream> using namespace std; #include<cmath> #include&l ...

  8. POJ 2986 A Triangle and a Circle 圆与三角形的公共面积

    计算几何模板 #include<stdio.h> #include<string.h> #include<stdlib.h> #include<math.h& ...

  9. Wannafly挑战赛25 B.面积并

    链接 [https://www.nowcoder.com/acm/contest/197/B] 分析 特殊优先考虑 首先考虑r>=l这种情况就是圆的面积了 第二就是r<=内切圆的半径,这个 ...

随机推荐

  1. ADO.Net学习总结

    一.讲述6个ADO.NET中的常用对象: Connection对象Command对象DataReader对象DataAdapter对象DataSet对象DataTable对象DataRow对象Data ...

  2. oracle ora-01652无法通过128(在表空间xxx中)扩展 问题解决方式

    问题原因建立的表空间dbf文件大小上限了 一. select * from dba_data_files 使用该条语句可以查看当前库中有多少表空间并且DBF文件的存储位置 二.查看表空间是否开启了自动 ...

  3. 再谈C#编码规范

    编码规范是老生常谈的问题,现在再看代码规范可能不会再去在意变量,控件的命名方法等,而是更加关注代码的实用性. 首先我们要明白一下几点, 1.代码写出来除了让他跑起来还有个非常非常重要的作用是维护,因为 ...

  4. Ubuntu切换阿里源

    sudo cp /etc/apt/sources.list /etc/apt/sources.list.bak #备份 sudo vim /etc/apt/sources.list #修改 sudo ...

  5. 打劫房屋 · House Robber

    [抄题]: 假设你是一个专业的窃贼,准备沿着一条街打劫房屋.每个房子都存放着特定金额的钱.你面临的唯一约束条件是:相邻的房子装着相互联系的防盗系统,且 当相邻的两个房子同一天被打劫时,该系统会自动报警 ...

  6. 282 expression and operations添加运算符

    [抄题]: 给定一个仅包含数字 0 - 9 的字符串和一个目标值,返回在数字之间添加了 二元 运算符(不是一元)+, - 或 * 之后所有能得到目标值的情况. "123", 6 - ...

  7. ADF控件ID变化引发JS无法定位控件的解决方法

    原文地址:ADF控件ID变化引发JS无法定位控件的解决方法作者:Nicholas JSFF定义的控件ID到了客户端时往往会改变.例如在JSFF中的一个的ID为"ot1",但是当这个 ...

  8. jvm编译环境搭建 win Vc篇

    /************************************************************** 技术博客 http://www.cnblogs.com/itdef/   ...

  9. GPS坐标换算为百度坐标(转)

    最近在做一个关于手机定位的小应用,需求是这样的,用户通过手机(Wp8)进行二维码扫描操作并且记录用户的当前位置,在PC上可以查看用户所在地图的位置,做法就是在用户扫描条码时,通过手机GPS获取当前在地 ...

  10. Android 实现在Activity中操作刷新另外一个Activity数据列表

    做android项目中遇到这样一个问题:有两个acticity,一个显示好友列表,另外一个显示会话列表,现在问题是在会话界面增加一个添加好友功能,添加好友后要求实时的刷新好友列表. 想了想,找了两种方 ...