HDU5023(A Corrupt Mayor's Performance Art)(第一个a了的pascal)

HDU5023(A Corrupt Mayor’s Performance Art)(pascal!!!)
http://acm.hdu.edu.cn/showproblem.php?pid=5023(题目)
题目大意
有n个数,m次操作,P操作是肮脏的市长对墙做肮脏的行为,把墙从a到b染成肮脏的颜色c,Q操作是询问有多少种肮脏的颜色在a和b之间。

题解
开始我觉得可以写三十棵线段树,然后好不容易写出来了结果空间爆了,果然这种弱智的做法还是不可以,然后,我开始认真的思考,觉得可以用压位来维护线段树中父亲节点的包含颜色,接着,多调试几遍就过了。这道题目唯一的难点就是行末一定不能有空格。

var
  x,y:array[0..4200000]of longint;
  n,m,i,j,k,a,b,c,res,p:longint;
  s:char;
procedure pushup(k:longint);
begin
  x[k]:=x[k*2] or x[k*2+1];
end;

procedure pushdown( k:longint);
var
  lc,rc:longint;
begin
  if(y[k]<>0)then
  begin
    lc:=k*2;
    rc:=k*2+1;
    y[lc]:=y[k];
    y[rc]:=y[k];
    x[lc]:=y[k];
    x[rc]:=y[k];
    y[k]:=0;
  end;
end;

procedure update(k,l,r:longint);
var
  lc,rc,mid:longint;
begin
  lc:=k*2;
  rc:=k*2+1;
  if(a<=l)and(r<=b)then
  begin
    y[k]:=1 shl (c-1);
    x[k]:=1 shl (c-1);
    exit;
  end;
  pushdown(k);
  mid:=(l+r)div 2;
  if(a<=mid)then update(lc,l,mid);
  if(b>mid)then update(rc,mid+1,r);
  pushup(k);
end;

function query(k,l,r:longint):longint;
var
  res,mid:longint;
begin
  if(a<=l)and(r<=b)then exit(x[k]);
  pushdown(k);
  res:=0;
  mid:=(l+r)div 2;
  if a<=mid then
    res:=res or query(k*2,l,mid);
  if b>mid then
    res:=res or query(k*2+1,mid+1,r);
  exit(res);
end;

procedure build(k,l,r:longint);
var
  mid:longint;
begin
  y[k]:=0;
  if(l=r)then
  begin
    x[k]:=2;
    exit;
  end;
  mid:=(l+r)div 2;
  build(k*2,l,mid);
  build(k*2+1,mid+1,r);
  pushup(k);
end;

begin
  n:=1;
  while(n<>0)or(m<>0)do
  begin
    readln(n,m);
    if(n=0)and(m=0)then halt;
    build(1,1,n);
    for m:=1 to m do
    begin
      read(s);
      if s='P' then
      begin
        read(a,b,c);
        update(1,1,n);
      end
      else
      begin
        read(a,b);
        p:=0;
        res:=query(1,1,n);
        for i:=1 to 30 do
        begin
          if(res and(1 shl(i-1))<>0)then
          begin
            if p=0 then
            write(i)
            else write(' ',i);
            p:=1;
          end;
        end;
        writeln;
      end;
      readln;
    end;
  end;
end.

这里写图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值