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<=内切圆的半径,这个 ...
随机推荐
- maven学习系列 之 常见问题
1.新建的maven项目无法修改 Project Facets 的 Dynamic Web Module 版本 RE: 在工程目录下有一个.settings文件夹,打开org.eclipse.wst. ...
- Rhythmk 学习 Hibernate 01 - maven 创建Hibernate 项目之 增删改查入门
1.环境: Maven :3.1.1 开发工具:Spring Tool Suite 数据库 : Mysql 5.6 2.项目文件结构 文件代码: 2.1 .pom.xml <project x ...
- C++ 获取特定进程的CPU使用率<转>
C++ 获取特定进程的CPU使用率 近来发现笔记本在关闭屏幕后风扇转得特别快,打开屏幕后看任务管理器,风扇马上减速,也没有发现大量占用CPU的进程.于是想写一个小程序在后台记录每个进程的CPU使用情况 ...
- zk分布式锁-排它锁简单实现-优化版
package Lock; import java.util.Collection;import java.util.Collections;import java.util.List;import ...
- linux img文件 分区挂载
首先是将制作的img文件比如hd5.img和loop设备建立联系. losetup /dev/loop0 hd5.img 然后用fdisk分区:fdisk /dev/loop0 mkfs.ext4 / ...
- node.js中实现同步操作的3种实现方法
这篇文章主要介绍了node.js中实现同步操作的3种实现方法,本文用实例讲解一些需要同步操作的情况下,如何编程实现,需要的朋友可以参考下 众所周知,异步是得天独厚的特点和优势,但同时在程序中同步的需求 ...
- 116. Populating Next Right Pointers in Each Node (Tree; WFS)
Given a binary tree struct TreeLinkNode { TreeLinkNode *left; TreeLinkNode *right; TreeLinkNode *nex ...
- SQL Server判断数据库、表、存储过程、函数是否存在
--判断数据库是否存在 if exists (select * from sys.databases where name = '数据库名') drop database [数据库名] --判断表是否 ...
- c语言伪常量const理解
const是伪常量,无法用于数组的初始化和全局变量的初始化,本质就是限定一个变量不能直接赋值. 如以下代码: #define A 10 int arr[A]; //const本质,伪常量 ,无法用于数 ...
- DevExress笔记
最近用DevExpress的WPF图表控件做柱形图看板,总结记录了一些笔记: 1.显示图例: <dxc:ChartControl.Legend> <dxc:Legend /> ...