题解:P3997 [SHOI2013] 扇形面积并
题意
将一个圆形分成
解题
题意转换
首先,这里先看一下怎么算一个小扇形的覆盖面积。设半径为
我们可以将题目转换为每一个小扇形中,覆盖了这个小扇形的所有大扇形有
思路
显然,每个大扇形都是连续的。那我们用一个树状数组,可以在某个地方把它加上,再在某个地方减去即可。因为要求第
Code
#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;
}