• 【BZOJ4418】[Shoi2013]扇形面积并 扫描线+线段树


    【BZOJ4418】[Shoi2013]扇形面积并

    Description

    给定N个同心的扇形,求有多少面积,被至少K个扇形所覆盖。

    Input

    第一行是三个整数n,m,k。n代表同心扇形的个数,m用来等分 [-π,π]的弧度。
    从第二行开始的n行,每行三个整数r,a1,a2。描述了一个圆心在原点的扇形,半径为r,圆心角是从弧度πa1/m到πa2/m,a1可能大于a2,逆时针扫过的区域为该扇形面积。

    Output

    输出一个整数ans,至少被K个扇形所覆盖的总面积等于π/2m×ans
    保证答案不超过2^63-1

    Sample Input

    【输入样例1】
    3 8 2
    1 -8 8
    3 -7 3
    5 -5 5
    【输入样例2】
    2 4 1
    4 4 2
    1 -4 4

    Sample Output

    【输出样例1】
    76
    【输出样例2】
    98

    HINT

    对于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;
    }
  • 相关阅读:
    Cocos2d-x 使用物理引擎进行碰撞检测
    Cocos2d粒子系统二
    cocos2d(粒子效果编辑器)
    关于Cococs中的CCActionEase(下)
    关于Cococs中的CCActionEase(中)
    关于Cococs中的CCActionEase
    call()和apply() 的区别
    WebStorm 使用快捷键大全
    WebStorm 的使用(一)
    导入xlsx,文件到sqlite3数据库
  • 原文地址:https://www.cnblogs.com/CQzhangyu/p/7859719.html
Copyright © 2020-2023  润新知