zoukankan      html  css  js  c++  java
  • 【POJ2528】Mayor's Posters-线段树+离散化

    (本人本题完成于2016-7-23)

    题目大意:有一面很长(10000000节)的墙,要在上面贴N张海报,对于第i张海报,它将会覆盖墙面的第Li~Ri节。刚开始墙面是空的,求最后还有多少张海报是可见的(即未被其他海报完全覆盖的)。

    以下是本人代码(貌似有瑕疵,可过官方数据,有待学习):

    #include <cstdio>
    #include <cstdlib>
    #include <cstring>
    #include <algorithm>
    using namespace std;
    int d,n,a[200010]={0},q[200010]={0},v[200010]={0},tot,ans;
    struct node
    {
      int l,r;
      int n; //n表示该区间最后被第n张海报完全覆盖,当n为0时表示不能确定
    }seg[600010];
    
    bool cmp(int a,int b)
    {
      return a<b;
    }
    
    void buildtree(int no,int l,int r)
    {
      int mid=(l+r)/2;
      seg[no].l=l;seg[no].r=r;seg[no].n=0;
      if (l!=r)
      {
        buildtree(2*no,l,mid);
    	buildtree(2*no+1,mid+1,r);
      }
    }
    
    void insert(int no,int s,int t,int i)
    {
      int mid=(seg[no].l+seg[no].r)/2;
      if (a[seg[no].l]>=s&&a[seg[no].r]<=t)
      {
        seg[no].n=i;
        return;
      }
      if (seg[no].n!=0)
      {
        seg[2*no].n=seg[2*no+1].n=seg[no].n;
        seg[no].n=0;
      }
      if (s<=a[mid]) insert(2*no,s,t,i);
      if (t>a[mid]) insert(2*no+1,s,t,i);
      if (seg[2*no].n==seg[2*no+1].n) seg[no].n=seg[2*no].n;
      else seg[no].n=0;
    }
    
    void query(int no)
    {
      if (seg[no].n!=0)
      {
        v[seg[no].n]=1;
    	return;
      }
      if (seg[no].l!=seg[no].r)
      {
        query(2*no);
    	query(2*no+1);
      }
    }
    
    int main()
    {
      scanf("%d",&d);
      for(int t=1;t<=d;t++)
      {
        memset(a,0,sizeof(a));
    	scanf("%d",&n);
    	for(int i=1;i<=n;i++)
    	{
    	  scanf("%d %d",&a[2*i-1],&a[2*i]);
    	  q[2*i-1]=a[2*i-1];q[2*i]=a[2*i];
    	}
    	sort(a+1,a+2*n+1,cmp);
    	tot=0;
    	for(int i=1;i<=2*n;i++) if (a[tot]!=a[i]) {tot++;a[tot]=a[i];} //离散化
    	buildtree(1,1,tot);
    	for(int i=1;i<=n;i++)
    	  insert(1,q[2*i-1],q[2*i],i);
    	memset(v,0,sizeof(v));
    	query(1);
    	ans=0;
    	for(int i=1;i<=n;i++) if (v[i]) ans++;
    	printf("%d
    ",ans);
      }
      
      return 0;
    }
    


  • 相关阅读:
    boost.property_tree的高级用法(你们没见过的操作)
    MFC- OnIdle空闲处理
    华为代码质量军规 (1) 数组访问,必须进行越界保护
    WinSocket 编程
    【C/C++】链表的理解与使用
    单链表
    C++ lambda表达式 (二)
    C++ lambda表达式 (一)
    C++11 volatile 类型
    关于结构体内存对齐方式的总结(#pragma pack()和alignas())
  • 原文地址:https://www.cnblogs.com/Maxwei-wzj/p/9794002.html
Copyright © 2011-2022 走看看