P3939 數顏色
題目描述
小 C 的兔子不是雪白的,而是五彩繽紛的。每只兔子都有一種顏色,不同的兔子可能有 相同的顏色。小 C 把她標號從 1 到 n 的 n只兔子排成長長的一排,來給他們餵胡蘿蔔吃。 排列完成後,第 iii 只兔子的顏色是 ai。
俗話說得好,“蘿蔔青菜,各有所愛”。小 C 發現,不同顏色的兔子可能有對胡蘿蔔的 不同偏好。比如,銀色的兔子最喜歡吃金色的胡蘿蔔,金色的兔子更喜歡吃胡蘿蔔葉子,而 綠色的兔子卻喜歡吃酸一點的胡蘿蔔……為了滿足兔子們的要求,小 C 十分苦惱。所以,為 了使得胡蘿蔔餵得更加準確,小 C 想知道在區間 [lj,rj]裏有多少只顏色為 cj? 的兔子。
不過,因為小 C 的兔子們都十分地活躍,它們不是很願意待在一個固定的位置;與此同 時,小 C 也在根據她知道的信息來給兔子們調整位置。所以,有時編號為 xj和 xj+1 的兩 只兔子會交換位置。 小 C 被這一系列麻煩事給難住了。你能幫幫她嗎?
輸入輸出格式
輸入格式:
從標準輸入中讀入數據。 輸入第 1 行兩個正整數 n , m。
輸入第 2 行 n 個正整數,第 i 個數表示第 i只兔子的顏色 ai? 。
輸入接下來 m 行,每行為以下兩種中的一種:
-
“ 1 lj rj cj ” :詢問在區間 [lj,rj]裏有多少只顏色為 cj的兔子;
-
“ 2 xj ”: xj 和 xj+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 數顏色