SHOI2013 扇形面积并
题目链接:戳我
补一张图
我们尝试把圆上的扇形转化成直线上的矩形——我们维护[1,2m]的区间,那么每个能产生贡献的子区间的长度第K大的半径的平方的总和就是answer了。
怎么转化呢?左端点为a1+m+1,右端点为a2+m。为什么要+m?因为原先的范围是[-m,m]的,所以整体右移。为什么左端点要+1?因为我们维护的是区间,所以这里的每一个下标表示的是以该position为右端点,长度为1的区间。
我们先按照半径长度从大到小排序,如果一个区间覆盖数量超过K个,就不需要再处理了。(优化时间复杂度)
之后就是线段树操作了。我们在更改的同时求出答案。(其实分开写也行,就是要注意因为我们乘上的系数使然,所以区间必须也是当前的修改区间)
minn表示该区间的所有子区间覆盖量的min,maxx是该区间的所有子区间的覆盖量的max。
注意我们的siz是由左右子区间合并而来的。所以产生贡献之后,记得赋值为0,这样就不会对它的父亲区间产生贡献了。
代码如下:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#define MAXN 2000010
using namespace std;
int n,m,k;
long long ans=0;
struct Node{int l,r,c;}node[MAXN];
struct Node2{int l,r,tag,minn,maxx,siz;}t[MAXN<<2];
inline bool cmp(struct Node x,struct Node y){return x.c>y.c;}
inline int ls(int x){return x<<1;}
inline int rs(int x){return x<<1|1;}
inline void push_up(int x)
{
t[x].maxx=max(t[ls(x)].maxx,t[rs(x)].maxx);
t[x].minn=min(t[ls(x)].minn,t[rs(x)].minn);
t[x].siz=t[ls(x)].siz+t[rs(x)].siz;
}
inline void build(int x,int l,int r)
{
t[x].l=l,t[x].r=r;
if(l==r) {t[x].siz=1;return;}
int mid=(l+r)>>1;
build(ls(x),l,mid);
build(rs(x),mid+1,r);
push_up(x);
}
inline void solve(int x,int k)
{
t[x].tag+=k;
t[x].minn+=k;
t[x].maxx+=k;
}
inline void push_down(int x)
{
int l=t[x].l,r=t[x].r;
if(t[x].tag)
{
solve(ls(x),t[x].tag);
solve(rs(x),t[x].tag);
t[x].tag=0;
}
}
inline int update_query(int x,int ll,int rr)
{
int l=t[x].l,r=t[x].r;
if(t[x].minn>=k) return 0;
if(ll<=l&&r<=rr)
{
if(t[x].maxx<k-1) {t[x].minn++,t[x].maxx++,t[x].tag++;return 0;}
if(t[x].minn>=k-1)
{
int cur_ans=t[x].siz;
t[x].siz=0;
t[x].minn++;
return cur_ans;
}
int cur_ans=0;
push_down(x);
cur_ans+=update_query(ls(x),ll,rr);
cur_ans+=update_query(rs(x),ll,rr);
push_up(x);
return cur_ans;
}
push_down(x);
int mid=(l+r)>>1;
int cur_ans=0;
if(ll<=mid) cur_ans+=update_query(ls(x),ll,rr);
if(mid<rr) cur_ans+=update_query(rs(x),ll,rr);
push_up(x);
return cur_ans;
}
int main()
{
#ifndef ONLINE_JUDGE
freopen("ce.in","r",stdin);
#endif
scanf("%d%d%d",&n,&m,&k);
for(int i=1;i<=n;i++)
{
scanf("%d%d%d",&node[i].c,&node[i].l,&node[i].r);
node[i].l+=m+1;
node[i].r+=m;
}
sort(&node[1],&node[n+1],cmp);
build(1,1,m*2);
for(int i=1;i<=n;i++)
{
int cur_ans=0;
if(node[i].l<node[i].r)
cur_ans+=update_query(1,node[i].l,node[i].r);
else if(node[i].l>node[i].r)
{
cur_ans+=update_query(1,node[i].l,m*2);
cur_ans+=update_query(1,1,node[i].r);
}
ans+=1ll*cur_ans*node[i].c*node[i].c;
//printf("i=%d ans=%lld\n",i,ans);
}
printf("%lld\n",ans);
return 0;
}
SHOI2013 扇形面积并的更多相关文章
- 【BZOJ4418】[Shoi2013]扇形面积并 扫描线+线段树
[BZOJ4418][Shoi2013]扇形面积并 Description 给定N个同心的扇形,求有多少面积,被至少K个扇形所覆盖. Input 第一行是三个整数n,m,k.n代表同心扇形的个数,m用 ...
- 4418: [Shoi2013]扇形面积并|二分答案|树状数组
为何感觉SHOI的题好水. ..又是一道SB题 从左到右枚举每个区间,遇到一个扇形的左区间就+1.遇到右区间就-1,然后再树状数组上2分答案,还是不会码log的.. SHOI2013似乎另一道题发牌也 ...
- bzoj4418 [Shoi2013]扇形面积并
传送门:http://www.lydsy.com/JudgeOnline/problem.php?id=4418 [题解] 被题目名称吓死系列. 用一棵线段树维护当前有哪些半径. 那么将扇形差分,每段 ...
- SHOI 2013 【扇形面积并】
早上考的,我打了80分的部分分,出来和同学讨论的时候真想扇自己一巴掌...... 题目描述: 给定 n 个同心的扇形,求有多少面积,被至少k 个扇形所覆盖. 输入输出格式 输入格式: 第一行是三个整数 ...
- OI题目类型总结整理
## 本蒟蒻的小整理qwq--持续更新(咕咕咕) 数据结构 数据结构 知识点梳理 数据结构--线段树 推荐yyb dalao的总结--戳我 以后维护线段树还是把l,r写到struct里面吧,也别写le ...
- bzoj AC倒序
Search GO 说明:输入题号直接进入相应题目,如需搜索含数字的题目,请在关键词前加单引号 Problem ID Title Source AC Submit Y 1000 A+B Problem ...
- 求两圆相交部分面积(C++)
已知两圆圆心坐标和半径,求相交部分面积: #include <iostream> using namespace std; #include<cmath> #include&l ...
- POJ 2986 A Triangle and a Circle 圆与三角形的公共面积
计算几何模板 #include<stdio.h> #include<string.h> #include<stdlib.h> #include<math.h& ...
- Wannafly挑战赛25 B.面积并
链接 [https://www.nowcoder.com/acm/contest/197/B] 分析 特殊优先考虑 首先考虑r>=l这种情况就是圆的面积了 第二就是r<=内切圆的半径,这个 ...
随机推荐
- ADO.Net学习总结
一.讲述6个ADO.NET中的常用对象: Connection对象Command对象DataReader对象DataAdapter对象DataSet对象DataTable对象DataRow对象Data ...
- oracle ora-01652无法通过128(在表空间xxx中)扩展 问题解决方式
问题原因建立的表空间dbf文件大小上限了 一. select * from dba_data_files 使用该条语句可以查看当前库中有多少表空间并且DBF文件的存储位置 二.查看表空间是否开启了自动 ...
- 再谈C#编码规范
编码规范是老生常谈的问题,现在再看代码规范可能不会再去在意变量,控件的命名方法等,而是更加关注代码的实用性. 首先我们要明白一下几点, 1.代码写出来除了让他跑起来还有个非常非常重要的作用是维护,因为 ...
- Ubuntu切换阿里源
sudo cp /etc/apt/sources.list /etc/apt/sources.list.bak #备份 sudo vim /etc/apt/sources.list #修改 sudo ...
- 打劫房屋 · House Robber
[抄题]: 假设你是一个专业的窃贼,准备沿着一条街打劫房屋.每个房子都存放着特定金额的钱.你面临的唯一约束条件是:相邻的房子装着相互联系的防盗系统,且 当相邻的两个房子同一天被打劫时,该系统会自动报警 ...
- 282 expression and operations添加运算符
[抄题]: 给定一个仅包含数字 0 - 9 的字符串和一个目标值,返回在数字之间添加了 二元 运算符(不是一元)+, - 或 * 之后所有能得到目标值的情况. "123", 6 - ...
- ADF控件ID变化引发JS无法定位控件的解决方法
原文地址:ADF控件ID变化引发JS无法定位控件的解决方法作者:Nicholas JSFF定义的控件ID到了客户端时往往会改变.例如在JSFF中的一个的ID为"ot1",但是当这个 ...
- jvm编译环境搭建 win Vc篇
/************************************************************** 技术博客 http://www.cnblogs.com/itdef/ ...
- GPS坐标换算为百度坐标(转)
最近在做一个关于手机定位的小应用,需求是这样的,用户通过手机(Wp8)进行二维码扫描操作并且记录用户的当前位置,在PC上可以查看用户所在地图的位置,做法就是在用户扫描条码时,通过手机GPS获取当前在地 ...
- Android 实现在Activity中操作刷新另外一个Activity数据列表
做android项目中遇到这样一个问题:有两个acticity,一个显示好友列表,另外一个显示会话列表,现在问题是在会话界面增加一个添加好友功能,添加好友后要求实时的刷新好友列表. 想了想,找了两种方 ...