JZOJ-senior-5960. 【NOIP2018模擬11.8A組】小喬
阿新 • • 發佈:2018-12-20
Time Limits: 1000 ms Memory Limits: 524288 KB
Description
Input
Output
Sample Input
3 8 2 1 -8 8 3 -7 3 5 -5 5
Sample Output
76
Data Constraint
Solution
很顯然,這個圖形可以被我們以某條線割開,拉出來變成一個線段上的問題,注意 的情況 這就變成了平面圖上的矩形覆蓋問題,問覆蓋次數不少於 次的面積 矩形覆蓋必須從最底往上,那下方覆蓋的次數會比上方多,符合二分的性質 我們採用掃描線,對於左端,把它加入樹狀陣列,右端,則刪去左端標記 採用樹狀陣列,對於每個位置,找出覆蓋它次數剛好為 的最外端並統計答案
Code
#include<algorithm>
#include<cstdio>
#define fo(i,a,b) for(int i=a;i<=b;++i)
#define fd(i,a,b) for(int i=a;i>=b;--i)
#define ll long long
using namespace std;
const int N=5e5+5,R=5e5+5,inf=1e9;
int n,m,k,cnt,c[R+5];
struct node{int x,r,k;}a[2*N];
bool cmp(node x, node y)
{
return x.x<y.x||x.x==y.x&&x.k>y.k;
}
void ins(int x,int y)
{
while(x<=R) c[x]+=y,x+=x&(-x);
}
int sum(int x)
{
if(!x) return inf;
int s=0;
while(x) s+=c[x],x-=x&(-x);
return s;
}
int find()
{
int l=0,r=R+1,out=0;
while(l<=r)
{
int mid=(l+r)>>1;
if (sum(mid)>=k) out=max(out,mid),l=mid+1;
else r=mid-1;
}
return out;
}
int main()
{
freopen("xiaoqiao.in","r",stdin);
freopen("xiaoqiao.out","w",stdout);
scanf("%d%d%d",&n,&m,&k);
fo(i,1,n)
{
int r,s,t;
scanf("%d%d%d",&r,&s,&t);
if(s<t)
{
a[++cnt]=(node){s,r,1};
a[++cnt]=(node){t,r,-1};
}
if(s>t)
{
a[++cnt]=(node){s,r,1};
a[++cnt]=(node){m,r,-1};
a[++cnt]=(node){-m,r,1};
a[++cnt]=(node){t,r,-1};
}
}
sort(a+1,a+1+cnt,cmp);
int i=1; ll ans=0;
fo(line,-m,m)
{
int r=find();
if(r<=R) ans=ans+(ll)r*r;
while(i<=cnt&&a[i].x<=line)
{
if(a[i].k>0) ins(1,1),ins(a[i].r+1,-1);
else ins(1,-1),ins(a[i].r+1,1);
++i;
}
}
printf("%lld",ans);
}