1. 程式人生 > >P3939 數顏色

P3939 數顏色

hellip query class 說明 十分 整數 -a space cdn

題目描述

小 C 的兔子不是雪白的,而是五彩繽紛的。每只兔子都有一種顏色,不同的兔子可能有 相同的顏色。小 C 把她標號從 1 到 nn只兔子排成長長的一排,來給他們餵胡蘿蔔吃。 排列完成後,第 iii 只兔子的顏色是 ai

俗話說得好,“蘿蔔青菜,各有所愛”。小 C 發現,不同顏色的兔子可能有對胡蘿蔔的 不同偏好。比如,銀色的兔子最喜歡吃金色的胡蘿蔔,金色的兔子更喜歡吃胡蘿蔔葉子,而 綠色的兔子卻喜歡吃酸一點的胡蘿蔔……為了滿足兔子們的要求,小 C 十分苦惱。所以,為 了使得胡蘿蔔餵得更加準確,小 C 想知道在區間 [lj,rj]裏有多少只顏色為 cj? 的兔子。

不過,因為小 C 的兔子們都十分地活躍,它們不是很願意待在一個固定的位置;與此同 時,小 C 也在根據她知道的信息來給兔子們調整位置。所以,有時編號為 xjxj+1 的兩 只兔子會交換位置。 小 C 被這一系列麻煩事給難住了。你能幫幫她嗎?

輸入輸出格式

輸入格式:

從標準輸入中讀入數據。 輸入第 1 行兩個正整數 n , m

輸入第 2 行 n 個正整數,第 i 個數表示第 i只兔子的顏色 ai?

輸入接下來 m 行,每行為以下兩種中的一種:

  • 1 lj rj cj ” :詢問在區間 [lj,rj]裏有多少只顏色為 cj的兔子;

  • 2 xj ”: xjxj+1 兩只兔子交換了位置。

輸出格式:

輸出到標準輸出中。

對於每個 1 操作,輸出一行一個正整數,表示你對於這個詢問的答案。

輸入輸出樣例

輸入樣例#1:
6 5 
1 2 3 2 3 3  
1 1 3 2 
1 4 6 3  
2 3 
1 1 3 2  
1 4 6 3
輸出樣例#1:
1 
2 
2 
3 

說明

【樣例 1 說明】

前兩個 1 操作和後兩個 1 操作對應相同;在第三次的 2 操作後,3 號兔子和 4 號兔子

交換了位置,序列變為 1 2 2 3 3 3。

【數據範圍與約定】

子任務會給出部分測試數據的特點。如果你在解決題目中遇到了困難,可以嘗試只解 決一部分測試數據。 對於所有測試點,有 1≤lj<rj≤n,1≤xj<n? 。 每個測試點的數據規模及特點如下表:

技術分享圖片

特殊性質 1:保證對於所有操作 1,有 ∣rj−lj∣≤20∣rj−lj∣≤n−20

特殊性質 2:保證不會有兩只相同顏色的兔子。

Solution:

  $6$月初真的不適合我碼題,什麽錯誤都出來了,調試總是搞半天`~`。。。

  算是主席樹模板題,維護每個顏色建立主席樹,因為顏色數$\leq 3*10^5$,所以不用離散。

  那麽每次加入一個顏色,就在

代碼:

 1 #include<bits/stdc++.h>
 2 #define il inline
 3 #define For(i,a,b) for(int (i)=(a);(i)<=(b);(i)++)
 4 using namespace std;
 5 const int N=300005;
 6 int n,m,sum[N*30],a[N],rt[N],ls[N*30],rs[N*30],cnt;
 7 
 8 il int gi(){
 9     int a=0;char x=getchar();
10     while(x<0||x>9)x=getchar();
11     while(x>=0&&x<=9)a=(a<<3)+(a<<1)+x-48,x=getchar();
12     return a;
13 }
14 
15 il void update(int l,int r,int pos,int c,int &rt){
16     if(!rt)rt=++cnt;
17     sum[rt]+=c;
18     if(l==r)return;
19     int m=l+r>>1;
20     if(pos<=m)update(l,m,pos,c,ls[rt]);
21     else update(m+1,r,pos,c,rs[rt]);
22 }
23 
24 il int query(int L,int R,int l,int r,int rt){
25     if(!rt)return 0;
26     if(L<=l&&R>=r)return sum[rt];
27     int m=l+r>>1,ret=0;
28     if(L<=m)ret+=query(L,R,l,m,ls[rt]);
29     if(m<R) ret+=query(L,R,m+1,r,rs[rt]);
30     return ret;
31 }
32 
33 int main(){
34     n=gi(),m=gi();    
35     For(i,1,n) a[i]=gi(),update(1,n,i,1,rt[a[i]]);
36     int f,x,y,z;
37     while(m--){
38         f=gi();
39         if(f==1){
40             x=gi(),y=gi(),z=gi();
41             printf("%d\n",query(x,y,1,n,rt[z]));
42         }
43         else {
44             x=gi();
45             update(1,n,x,-1,rt[a[x]]);
46             update(1,n,x+1,-1,rt[a[x+1]]);
47             update(1,n,x+1,1,rt[a[x]]);
48             update(1,n,x,1,rt[a[x+1]]);
49             swap(a[x],a[x+1]);
50         }
51     }
52     return 0;
53 }

P3939 數顏色