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<=内切圆的半径,这个 ...
随机推荐
- shell脚本实现tomcat进程—查、杀、启
#!/bin/bash#获取XXX项目进程IDXXXpid=`ps -ef | grep XXX | grep -v grep | awk '{print $2}'` echo "XXX项目 ...
- docker field
- centos7.3 防火墙设置
1.查看firewall服务状态 systemctl status firewalld 2.查看firewall的状态 firewall-cmd --state 3.开启.重启.关闭.firewall ...
- Grapher
[Grapher] You use Grapher to visualize and analyze implicit and explicit equations. You can graph eq ...
- 利用WKWebView实现js与OC交互注意事项
最近在写一些关于wkwebview的一些代码,发现了几点心得,记录一下. 1.js调用OC 我是利用wkwebview进行的开发实现,主要代码有三部分 1.向config注入OC对象 [config. ...
- 通过curl模拟多线程抓取网页(curl_multi_*)
curl请求多个url,以前都是使用循环来处理.最近发现可以通过curl_multi_*系列函数来模拟多线程.比对一下,发现如果请求的url只有几个,2种方案耗时差不多,但是url比较多,差距就非常明 ...
- Qt的安装和使用中的常见问题(简略版)
对于喜欢研究细节的朋友,可参考Qt的安装和使用中的常见问题(详细版). 目录 1.引入 2.Qt简介 3.Qt版本 3.1 查看安装的Qt版本 3.2 查看当前项目使用的Qt版本 3.3 查看当前项目 ...
- HBase 系列(三)HBase Shell
HBase 系列(三)HBase Shell ./hbase shell # 进入 hbase 命令行 (1) HBase 命令帮助 help # 查看 HBase 所有的命令 create # 或 ...
- 个人如何免费申请一个微信小程序账号进行开发尝鲜
大家都知道微信小程序并没有开放个人申请注册账号,觉得很遗憾,作为一个开发者,居然不能一览究竟. 前段时间研究了一番,教大家如何个人申请注册一个小程序账号,不花300块钱,当然只能作为开发尝鲜,不能发布 ...
- 如何讓 iOS UIWebView 連線時傳送自訂 Cookie 的方法[转]
利用 NSHTTPCookieStorage 管理 Cookie 傳送 在 iOS 中如果自行建立 UIWebView 來開啟遠端站台資料,這時可以透過以下方法加入 Cookie.原理是透過 iOS ...