1. 程式人生 > >JZOJ 4603 顏料大亂鬥【NOIP2016提高A組模擬7.15】

JZOJ 4603 顏料大亂鬥【NOIP2016提高A組模擬7.15】

顏色大亂鬥

題目描述

這裡寫圖片描述

輸入格式

這裡寫圖片描述

輸出格式

這裡寫圖片描述

樣例輸入

2 2 4
C 1 1 2
P 1 2
C 2 2 2
P 1 2

樣例輸出

2
1

資料範圍

這裡寫圖片描述

題解

這一題,題目要求維護加詢問區間,那我們種30棵線段樹維護一段區間中每種顏色的種類數即可。
記得在打線段樹時加上懶惰遷移。
統計答案和更新區間以及懶惰標記下傳時,只需用c的時間去做就可以了,反正時間複雜度不會太大。

Code(Pascal)

const
    kt=1;
var
    ch:char;
    tj:array[0..100] of longint;
    n,c,m,i,j,k,l,o,p,ans,x,y,t,u:longint;
    la:array
[0..300000] of longint; tr:array[0..300000,0..30] of longint; procedure jl(o,l,r:longint); var mid:longint; begin tr[o,kt]:=r-l+1; if l=r then exit; mid:=(l+r) div 2; jl(o*2,l,mid); jl(o*2+1,mid+1,r); end; procedure draw(o,l,r,ll,rr,cqy:longint); var
ls,rs,i,mid:longint; begin mid:=(l+r) div 2; ls:=O*2; rs:=ls+1; if (l=ll) and (r=rr) then begin la[o]:=cqy; for i:=kt to c do tr[o,i]:=0; tr[o,cqy]:=r-l+1; exit; end; if la[o]>0
then begin for i:=kt to c do begin tr[ls,i]:=0; tr[rs,i]:=0; end; tr[ls,la[o]]:=mid-l+1; tr[rs,la[o]]:=r-mid; la[ls]:=la[o]; la[rs]:=la[o]; la[o]:=0; end; if rr<=mid then draw(ls,l,mid,ll,rr,cqy) else if ll>mid then draw(rs,mid+1,r,ll,rr,cqy) else begin draw(ls,l,mid,ll,mid,cqy); draw(rs,mid+1,r,mid+1,rr,cqy); end; for i:=kt to c do tr[o,i]:=tr[ls,i]+tr[rs,i]; end; procedure cx(o,l,r,ll,rr:longint); var ls,rs,mid,i:longint; begin if (l=ll) and (r=rr) then begin for i:=kt to c do tj[i]:=tj[i]+tr[o,i]; exit; end; mid:=(l+r) div 2; ls:=o*2; rs:=ls+1; if la[o]>0 then begin for i:=kt to c do begin tr[ls,i]:=0; tr[rs,i]:=0; end; tr[ls,la[o]]:=mid-l+1; tr[rs,la[o]]:=r-mid; la[ls]:=la[o]; la[rs]:=la[o]; la[o]:=0; end; if rr<=mid then cx(ls,l,mid,ll,rr) else if ll>mid then cx(rs,mid+1,r,ll,rr) else begin cx(ls,l,mid,ll,mid); cx(rs,mid+1,r,mid+1,rr); end; for i:=kt to c do tr[o,i]:=tr[ls,i]+tr[rs,i]; end; begin readln(n,c,m); jl(1,1,n); for i:=1 to m do begin read(ch); if ch='C' then begin readln(x,y,t); if x>y then begin u:=x; x:=y; y:=u; end; draw(1,1,n,x,y,t); end else begin readln(x,y); if x>y then begin u:=x; x:=y; y:=u; end; for l:=kt to c do tj[l]:=0; cx(1,1,n,x,y); ans:=0; for l:=kt to c do if tj[l]>0 then inc(ans); writeln(ans); end; end; end.