1. 程式人生 > >BZOJ2120/洛谷P1903 [國家集訓隊] 數顏色 [帶修改莫隊]

BZOJ2120/洛谷P1903 [國家集訓隊] 數顏色 [帶修改莫隊]

swa lin change badge swap truct AC htm for

  BZOJ傳送門;洛谷傳送門

數顏色

題目描述

墨墨購買了一套N支彩色畫筆(其中有些顏色可能相同),擺成一排,你需要回答墨墨的提問。墨墨會向你發布如下指令:

1、 Q L R代表詢問你從第L支畫筆到第R支畫筆中共有幾種不同顏色的畫筆。

2、 R P Col 把第P支畫筆替換為顏色Col。

為了滿足墨墨的要求,你知道你需要幹什麽了嗎?

輸入輸出格式

輸入格式:

第1行兩個整數N,M,分別代表初始畫筆的數量以及墨墨會做的事情的個數。

第2行N個整數,分別代表初始畫筆排中第i支畫筆的顏色。

第3行到第2+M行,每行分別代表墨墨會做的一件事情,格式見題幹部分。

輸出格式:

對於每一個Query的詢問,你需要在對應的行中給出一個數字,代表第L支畫筆到第R支畫筆中共有幾種不同顏色的畫筆。

輸入輸出樣例

輸入樣例#1: 復制
6 5
1 2 3 4 5 5
Q 1 4
Q 2 6
R 1 2
Q 1 4
Q 2 6
輸出樣例#1: 復制
4
4
3
4

  分析:

  一開始不會打帶修改莫隊,就直接打了個不帶分塊的普通莫隊,然後在洛谷水了40分,然後看了某位大佬的博客以後,會了帶修改莫隊,結果被洛谷數據卡常卡了一個小時,這數據也太可怕了吧。。。給出數據的人跪了Orz。。。(BZOJ上的數據一遍就過了。。。)把能用的優化都丟進去了,然後8000+ms過的。。。如果不會帶修改莫隊,請參考這位大佬的博客。這裏蒟蒻就只放代碼了。

  Code:

 1 //It is made by HolseLee on 31st May 2018
 2 //Luogu.org P1903
 3 #include<bits/stdc++.h>
 4 #define swap(x,y) x^=y,y^=x,x^=y
 5 using namespace std;
 6 const int N=5e4+7;
 7 const int M=1e6+7;
 8 int n,m,s,L,R,tot,ans[N];
 9 int a[N],c[M],rn,qn;
10 struct Node{
11     int
x,y,id,pos; 12 friend bool operator < (const Node a,const Node b){ 13 if((a.x-1)/s!=(b.x-1)/s)return ((a.x-1)/s)<((b.x-1)/s); 14 if((a.y-1)/s!=(b.y-1)/s)return ((a.y-1)/s)<((b.y-1)/s); 15 return a.id<b.id; 16 } 17 }Q[N]; 18 struct Num{ 19 int x,y;}C[N]; 20 char obuf[1<<24], *O=obuf; 21 inline int read() 22 { 23 char ch=getchar();int num=0; 24 while(ch<0||ch>9)ch=getchar(); 25 while(ch>=0&&ch<=9){ 26 num=num*10+ch-0;ch=getchar();} 27 return num; 28 } 29 inline void print(int x) 30 { 31 if(x>9)print(x/10); 32 *O++ = x%10+0; 33 } 34 inline void change(int x,int i) 35 { 36 if(Q[i].x<=C[x].x&&C[x].x<=Q[i].y){ 37 if(--c[a[C[x].x]]==0)tot--; 38 if(++c[C[x].y]==1)tot++; } 39 swap(a[C[x].x],C[x].y); 40 } 41 inline void add(int x) 42 {if(++c[a[x]]==1)tot++;} 43 inline void del(int x) 44 {if(--c[a[x]]==0)tot--;} 45 inline void work() 46 { 47 sort(Q+1,Q+qn+1);int now=0; 48 for(int i=1;i<=qn;i++){ 49 while(L<Q[i].x)del(L++); 50 while(L>Q[i].x)add(--L); 51 while(R<Q[i].y)add(++R); 52 while(R>Q[i].y)del(R--); 53 while(now<Q[i].id){change(++now,i);} 54 while(now>Q[i].id){change(now--,i);} 55 ans[Q[i].pos]=tot;} 56 for(int i=1;i<=qn;i++) 57 {print(ans[i]);*O++ = \n;} 58 } 59 int main() 60 { 61 n=read();m=read(); 62 for(int i=1;i<=n;i++)a[i]=read(); 63 for(int i=1;i<=m;i++){ 64 char ch[5];scanf("%s",ch); 65 int x=read();int y=read(); 66 if(ch[0]==R){C[++rn].x=x;C[rn].y=y;} 67 else {Q[++qn].x=x;Q[qn].y=y; 68 Q[qn].id=rn;Q[qn].pos=qn;}} 69 s=ceil(exp((log(n)+log(qn))/3));L=1;R=0; 70 work();fwrite(obuf, O-obuf, 1, stdout); 71 return 0; 72 }

BZOJ2120/洛谷P1903 [國家集訓隊] 數顏色 [帶修改莫隊]