给定N个同心的扇形,求有多少面积,被至少K个扇形所覆盖。
标签:hup strong int out sof cpp nod 半径 while
对于100%的数据,1≤n≤10^5, 1≤m≤10^6,1≤k≤5000,1≤ri≤10^5,-m≤a1,a2≤m
题解:现将扇形掰开变成矩形,然后用扫描线处理,每个矩形都改成差分的形式。由于对于任意一条与x轴垂直的先,里面的点被覆盖的层数一定不会比外面少,所以我们可以在线段树上二分,时间复杂度$O(nlogr)$。
#include <cstdio> #include <cstring> #include <iostream> #include <algorithm> #define lson x<<1 #define rson x<<1|1 using namespace std; const int maxn=100010; typedef long long ll; int n,m,tot,R,K; int s[maxn<<2]; ll ans; struct node { int x,y,k; node() {} node(int a,int b,int c) {x=a,y=b,k=c;} }p[maxn<<2]; bool cmp(const node &a,const node &b) { return a.x<b.x; } inline void pushup(int x) { s[x]=s[lson]+s[rson]; } void updata(int l,int r,int x,int a,int b) { s[x]+=b; if(l==r) return ; int mid=(l+r)>>1; if(a<=mid) updata(l,mid,lson,a,b); else updata(mid+1,r,rson,a,b); } int query(int l,int r,int x,int a) { if(l==r) return l; int mid=(l+r)>>1; if(s[rson]>=a) return query(mid+1,r,rson,a); return query(l,mid,lson,a-s[rson]); } inline int rd() { int ret=0,f=1; char gc=getchar(); while(gc<‘0‘||gc>‘9‘) {if(gc==‘-‘) f=-f; gc=getchar();} while(gc>=‘0‘&&gc<=‘9‘) ret=ret*10+(gc^‘0‘),gc=getchar(); return ret*f; } int main() { n=rd(),m=rd(),K=rd(); int i,a,b,c; for(i=1;i<=n;i++) { c=rd(),a=rd()+m,b=rd()+m,R=max(R,c); if(a<=b) p[++tot]=node(a,c,1),p[++tot]=node(b,c,-1); else p[++tot]=node(a,c,1),p[++tot]=node(2*m,c,-1),p[++tot]=node(0,c,1),p[++tot]=node(b,c,-1); } sort(p+1,p+tot+1,cmp); for(i=1;i<=tot;i++) { a=query(0,R,1,K),ans+=(ll)a*a*(p[i].x-p[i-1].x); updata(0,R,1,p[i].y,p[i].k); } printf("%lld",ans); return 0; }
【BZOJ4418】[Shoi2013]扇形面积并 扫描线+线段树
标签:hup strong int out sof cpp nod 半径 while
原文地址:http://www.cnblogs.com/CQzhangyu/p/7859719.html