Link
Luogu - https://www.luogu.org/problemnew/show/P3997
BZOJ - https://www.lydsy.com/JudgeOnline/problem.php?id=4418
假如你也听说校门外的树
容易考虑利用差分前缀和
……但是这道题扇形半径不定
怎么办?
我们依然可以知道哪些角度区间被不少于
k
k
k 个扇形覆盖
然后每个这样的角度如果被
x
x
x 个扇形覆盖
那么这个角度产生贡献的半径是覆盖它的扇形里面半径第
x
−
k
+
1
x-k+1
x−k+1 小那个扇形的半径
产生的贡献是这个半径的平方
来一发扫描线就完事了
你也可以考虑直接覆盖,不过 Lazytag 不好做,复杂度貌似有点假(?)
注意题目说得很不清楚……
a
1
>
a
2
a_1>a_2
a1>a2 的时候这个扇形过角度
π
\pi
π
我好菜啊
人傻BUG多
#include<cstdio>
#include<iostream>
#include<algorithm>
using namespace std;
//#define _Rep(i,j,k) for(register int i=(j);i<=(k);++i)
const int MAXN = 2e5+5;
const int MAXM = 2e6+5;
const int MAXR = 1e5;
const int MAXS = (MAXR<<2)+5;
int n, m, M, k, tot;
#define PII pair<int, int>
PII Mark[MAXM];
int Seg[MAXS], Siz[MAXS];
long long Ans;
//int X[MAXN], L[MAXN], R[MAXN], Id[MAXN];
//inline bool cmp(const int& a, const int& b)
//{
// return (X[a]==X[b])?((L[a]==L[b])?(R[a]>R[b]):(L[a]>L[b])):(X[a]>X[b]);
//}
void Insert(const int& Pos, const int& L, const int& R, const int& Val, const bool& ar)
{
Siz[Pos]+=ar?1:-1;
if (L == R) return;
int Mid = L + R >> 1;
if (Val <= Mid) Insert(Pos << 1, L, Mid, Val, ar);
else Insert(Pos<<1|1, Mid + 1, R, Val, ar);
}
inline int defabs(const int& x)
{
return (x<0)?(-x):x;
}
inline long long PWO(const int& x)
{
return 1ll * x * x;
}
inline int Query(const int& Pos, const int& L, const int& R, const int& kth)
{
if(L==R) return L;
int Mid = L + R >> 1;
if(Siz[Pos<<1|1]<kth) return Query(Pos<<1, L, Mid, kth-Siz[Pos<<1|1]);
else return Query(Pos<<1|1, Mid + 1, R, kth);
}
int main()
{
scanf("%d%d%d", &n, &m, &k);
M = m << 1;
for (register int x, l, r, i = 1; i <= n; ++i)
{
// ++tot;
// scanf("%d%d%d", &X[tot], &L[tot], &R[tot]);
// L[tot] += m, R[tot] += m - 1;
// if (L[tot]>R[tot])
// {
// R[tot+1]=R[tot],L[tot+1]=0;
// R[tot++]=M;
// }
scanf("%d%d%d", &x, &l, &r);
l += m; r += m - 1;
if(r==M)r=0;
if(l<=r)Mark[++tot]=make_pair(l,x),Mark[++tot]=make_pair(r+1,-x);
else Mark[++tot]=make_pair(l,x),Mark[++tot]=make_pair(M,-x),Mark[++tot]=make_pair(0,x),Mark[++tot]=make_pair(r+1,-x);
}
sort(Mark+1,Mark+tot+1);
// _Rep(i, 1, tot) Id[i]=i;
// sort(Id+1,Id+1+tot,cmp);
for (register int MarkPos = 1, i = 0; i <= M; ++i)
{
while(Mark[MarkPos].first<i && MarkPos <= tot)++MarkPos;
while(Mark[MarkPos].first==i && MarkPos <= tot)
{
Insert(1, 0, MAXR+1, defabs(Mark[MarkPos].second), Mark[MarkPos].second>0);
++MarkPos;
}
Ans += PWO(Query(1, 0, MAXR+1, k));
}
printf("%lld", Ans);
return 0;
}