专栏文章
题解:P3997 [SHOI2013] 扇形面积并
P3997题解参与者 1已保存评论 0
文章操作
快速查看文章及其快照的属性,并进行相关操作。
- 当前评论
- 0 条
- 当前快照
- 1 份
- 快照标识符
- @miq0zyux
- 此快照首次捕获于
- 2025/12/03 21:11 3 个月前
- 此快照最后确认于
- 2025/12/03 21:11 3 个月前
题意
将一个圆形分成 个小扇形,在给出 个大扇形,第 个扇形半径为 。给上方的的扇形逆时针编号为正,下方顺时针编号为负,则大扇形就是覆盖了第 个小扇形转到到第 个扇形。求至少被 个大扇形覆盖的面积,设答案为 。则输出 。这里先给一张图。


解题
题意转换
首先,这里先看一下怎么算一个小扇形的覆盖面积。设半径为 。则面积为 。
我们可以将题目转换为每一个小扇形中,覆盖了这个小扇形的所有大扇形有 个。则这块小扇形的贡献就是其中半径第 大的大扇形在这块小扇形中的面积。也就是说因为需要求至少被 个大扇形覆盖的地方的面积,所以每块小扇形有了 个大扇形的覆盖之后就从半径最小的大扇形开始算。
思路
Code
CPP#include<bits/stdc++.h>
#define int long long
using namespace std;
int n,k,m,ans,luozhi;
int c[3000000];
vector<int> tree[3000000];
int lowbit(int x){
return x&(-x);
}
void change(int k,int x){
for(int i=x;i<=100000;i+=lowbit(i))c[i]+=k;
}
int sum(int id){
int x=0,k=0,y=0,cnt=0;
for(int i=21;~i;i--){
x=k+(1<<i);if(x>100000) continue;
y=cnt+c[x];
if(y<id)k=x,cnt=y;
}
return k+1;
}
signed main(){
cin>>n>>m>>k;
for(int i=1;i<=n;i++){
int r,s,t;
cin>>r>>s>>t,s+=m,t+=m;
if(s<t){
tree[s].push_back(-r);
tree[t].push_back(r);
}
else{
tree[m*2].push_back(r);
tree[s].push_back(-r);
tree[t].push_back(r);
}
}
for(int i=2*m;i>=1;i--){
for(int j=0;j<tree[i].size();j++){
int e=tree[i][j];
if(e>0)change(1,e),luozhi++;
else change(-1,-e),luozhi--;
}
if(luozhi>=k)ans+=sum(luozhi-k+1)*sum(luozhi-k+1);
}
cout<<ans;
}
相关推荐
评论
共 0 条评论,欢迎与作者交流。
正在加载评论...