zoukankan      html  css  js  c++  java
  • [poj2528]求最后未完全被其它线段覆盖的线段个数

    大意:给出N<=10000个线段,每个数l,r<=10000000,求最后未被完全覆盖的线段条数。

    解答:先离散化,再线段树,每次记录一下每个区间被那一个覆盖,最后扫一遍即可。

    program poj2528;
    
    Type
     re=record
      l,r,cover:longint;
     end;
     
    Var
     a:array[0..20000] of re;
     z:array[0..40000] of longint;
     n,o,all,i,top:longint;
     f:array[0..180000] of re;
     t:array[0..20000] of boolean;
     ans:longint;
     
    Function max(a,b:longint):longint;
      begin
      if a>b then exit(a) else exit(b);
    end;
    
    Function min(a,b:longint):longint;
      begin
      if a<b then exit(a) else exit(b);
    end;
    
    Procedure lsh(var a:array of longint;k:longint);
    Type
     rec=record
       pos:longint;
       num:longint;
     end;
     
    Var
     b:array[0..100000] of rec;
     i,now,last:longint;
    
    Procedure qsort(var b:array of rec;l,r:longint);
    var
     i,j:longint;
     x,y:rec;
      begin
      i:=l;j:=r;x:=b[random(r-l+1)+l];
        repeat
        while b[i].num<x.num do inc(i);
        while b[j].num>x.num do dec(j);
        if i<=j then
          begin
          y:=b[i];
          b[i]:=b[j];
          b[j]:=y;
          inc(i);
          dec(j);
        end;
      until i>j;
      if l<j then qsort(b,l,j);
      if i<r then qsort(b,i,r);
    end;
    
      begin
      for i:=1 to k do
        with b[i] do
          begin
          num:=a[i];
          pos:=i;
        end;
      qsort(b,1,k);
      now:=1;
      a[b[1].pos]:=1;
      last:=1;
      for i:=2 to k do
        begin
        if b[i-1].num<>b[i].num then
          begin
          last:=i;
          inc(now);
        end;
        a[b[i].pos]:=now;
      end;
    end;
    
    Procedure build(p:longint);
      begin
    	if f[p].l=f[p].r then exit;
    	f[p*2].l:=f[p].l;
    	f[p*2].r:=(f[p].l+f[p].r) div 2;
    	f[p*2+1].l:=(f[p].l+f[p].r) div 2+1;
    	f[p*2+1].r:=f[p].r;
    	build(p*2);
    	build(p*2+1);
    end;
    
    Procedure pushdata(P:longint);
      begin
    	if f[p].cover<>0 then
    	  begin
    		f[p*2].cover:=f[p].cover;
    		f[p*2+1].cover:=f[p].cover;
    		f[p].cover:=0;
    	end;
    end;
    
    Procedure insert(p,pl,pr,v:longint);
    var
     mid:longint;
      begin
    //	writeln('#',p,' ',pl,' ',pr,' ',v,' ',f[p].l,' ',f[p].r);
    	if (f[p].l=pl) and (f[p].r=pr) then
    	  begin
    		f[p].cover:=v;
    		exit;
    	end;
    	pushdata(p);
    	mid:=(f[p].l+f[p].r) div 2;
    	if pl<=mid then insert(p*2,pl,min(mid,pr),v);
    	if pr>mid then insert(p*2+1,max(mid+1,pl),pr,v);
    end;
    
    Procedure visit(P:longint);
      begin
    //	writeln(p,' ',f[p].l,' ',f[p].r,' ',f[p].cover);
    	if f[p].cover<>0 then
    	  begin
    		t[f[p].cover]:=true;
    		exit;
    	end;
    	if f[p].l=f[p].r then exit;
    	visit(p*2);
    	visit(p*2+1);
    end;
    	
      begin
    	readln(o);
    	for all:=1 to o do begin
    	readln(n);
    	for i:=1 to n do
    	  begin
    		readln(a[i].l,a[i].r);
    		z[i*2-1]:=a[i].l;
    		z[i*2]:=a[i].r;
    	end;
    	lsh(z,n*2);
    	for i:=1 to n*2 do
    	  if i mod 2=1 then 
    		  a[(i-1) div 2+1].l:=z[i] else
    			a[(i-1) div 2+1].r:=z[i];
    			
    		
    	fillchar(f,sizeof(f),0);		
    	f[1].l:=1;
    	f[1].r:=40000;
    	build(1);
    	for i:=1 to n do
    	  insert(1,a[i].l,a[i].r,i);
    	fillchar(t,sizeof(t),false);
    	top:=1;
    	while f[top].r>=2*n do top:=top*2;
      top:=top div 2;
      visit(top);	
    	ans:=0;
    	for i:=1 to n do
    	  if t[i] then inc(ans);
    	writeln(ans);
    	end;
    
    end.
    
  • 相关阅读:
    0099 数据类型转换 之 转为布尔:Boolean()
    0098 数据类型转换 之 转为数字: parseInt 、 parseFloat 、Number()、隐式转换
    0097 数据类型转换 之 转为字符串:toString()、String() 、加号拼接、隐式转换
    0096 获取变量数据类型typeof、字面量
    0095 布尔型Boolean,Undefined和 Null
    0094 字符串型 String
    0093 数字型 Number:整数、小数 、数字型进制、数字型范围、数字型三个特殊值、isNaN
    0092 数据类型、简单数据类型概述
    0091 交换两个变量的值( 实现思路:使用一个 临时变量 用来做中间存储 )
    SCSS 常用属性合集
  • 原文地址:https://www.cnblogs.com/htfy/p/2515311.html
Copyright © 2011-2022 走看看