zoukankan      html  css  js  c++  java
  • 猴戏世家 解题报告

    Problem A: 猴戏世家


    考试时拿染色企图水20分结果hash冲突了,rp++

    考虑离线乱搞一下,可以先把每个点最开始被哪个矩形包着求出来,然后把矩形被哪个矩形包着求出来。

    这样点作为对矩形的贡献成为矩形的权,矩形连边后形成一把森林。

    按y从大到小进行扫描线,拿set维护这个扫描线,每次加入矩形时把自己左边比自己晚的扔掉,然后随便维护一下连边和权值。

    然后考虑到每个矩形可以对完全包含它的矩形做贡献,于是我们倒序删除矩形,维护一个带权并查集,每次把贡献扔给父亲就可以了


    Code:

    #include <cstdio>
    #include <algorithm>
    #include <vector>
    #include <set>
    const int N=6e5+10;
    int n,m,mx[N],my[N],qx[N],qy[N],d[N],cnt;
    struct beecute
    {
    	int p,id;
    	beecute(){}
    	beecute(int p,int id){this->p=p,this->id=id;}
    	bool friend operator <(beecute a,beecute b){return a.p==b.p?a.id<b.id:a.p<b.p;}
    };
    std::vector<beecute> bee[N];
    std::set <beecute> s;
    std::set <beecute>::iterator it;
    int par[N],f[N],val[N],ans[N];
    int Find(int x){return f[x]=f[x]==x?x:Find(f[x]);}
    void Merge(int x,int y)
    {
    	f[x]=Find(y);
    	val[f[x]]+=val[x];
    }
    int main()
    {
    	scanf("%d",&n);
    	for(int i=1;i<=n;i++) scanf("%d%d",mx+i,my+i),d[++cnt]=my[i];
    	scanf("%d",&m);
    	for(int i=1;i<=m;i++) scanf("%d%d",qx+i,qy+i),d[++cnt]=qy[i],f[i]=i;
    	std::sort(d+1,d+1+cnt);
    	cnt=std::unique(d+1,d+1+cnt)-d-1;
    	for(int i=1;i<=n;i++)
    	{
    		my[i]=std::lower_bound(d+1,d+1+cnt,my[i])-d;
    		bee[my[i]].push_back(beecute(mx[i],0));
    	}
    	for(int i=1;i<=m;i++)
    	{
    		qy[i]=std::lower_bound(d+1,d+1+cnt,qy[i])-d;
    		bee[qy[i]].push_back(beecute(qx[i],i));
    	}
    	for(int i=cnt;i;i--)
    	{
    		std::sort(bee[i].begin(),bee[i].end());
    		for(int j=bee[i].size()-1;~j;j--)
    		{
    			int id=bee[i][j].id;
    			it=s.lower_bound(bee[i][j]);
    			if(id)
    			{
    				if(it!=s.end())
                        par[id]=it->id;
                    if(it==s.begin()) {s.insert(bee[i][j]);continue;}
                    --it;
    				while(it!=s.begin()&&it->id>id)
                        s.erase(it--);
    				if(!s.empty()&&it==s.begin()&&it->id>id)
    				    s.erase(it);
    				s.insert(bee[i][j]);
    			}
    			else if(it!=s.end())
                    ++val[it->id];
    		}
    	}
    	for(int i=m;i;i--)
    	{
    		ans[i]=val[i];
    		Merge(i,par[i]);
    	}
    	for(int i=1;i<=m;i++) printf("%d
    ",ans[i]);
    	return 0;
    }
    

    2019.1.18

  • 相关阅读:
    怎么对Navicat for Oracle 调试
    老版本的java代码与新代码如何找出差异
    Oracle 外部表是做什么用的
    如何在Navicat 中编辑和记录
    如何使用文件对比工具文件夹比较会话菜单
    哪些工具可以用来进行Bug管理
    5类开发者须知的工具
    怎么找出代码之间的差异
    Beyond Compare不仅可以修改网页代码
    文件对比工具有哪些用途
  • 原文地址:https://www.cnblogs.com/butterflydew/p/10289307.html
Copyright © 2011-2022 走看看