給出一個長爲 nnn 的數列,以及 nnn 個操做,操做涉及區間詢問等於一個數 ccc 的元素,並將這個區間的全部元素改成 ccc。html
第一行輸入一個數字 nnn。ios
第二行輸入 nnn 個數字,第 i 個數字爲 aia_iai,以空格隔開。ui
接下來輸入 nnn 行詢問,每行輸入三個數字 lll、rrr、ccc,以空格隔開。spa
表示先查詢位於 [l,r][l,r][l,r] 的數字有多少個是 ccc,再把位於 [l,r][l,r][l,r] 的數字都改成 ccc。code
對於每次詢問,輸出一行一個數字表示答案。htm
4 1 2 2 4 1 3 1 1 4 4 1 2 2 1 4 2
1 1 0 2
對於 100% 100\%100% 的數據,1≤n≤100000,−231≤others 1 \leq n \leq 100000, -2^{31} \leq \mathrm{others}1≤n≤100000,−231≤others、ans≤231−1 \mathrm{ans} \leq 2^{31}-1ans≤231−1。blog
維護區間是不是連續的相同值ip
#include<iostream> #include<cstdio> #include<cstring> #include<cmath> #define maxn 100010 using namespace std; int n,m,block,a[maxn],tag[maxn],pos[maxn]; bool cover[maxn]; int findl(int id){return (id-1)*block+1;} int findr(int id){return min(id*block,n);} void reset(int id,int l,int r,int v1,int v2){ for(int i=findl(id);i<l;i++)a[i]=v1; for(int i=l;i<=r;i++)a[i]=v2; for(int i=r+1;i<=findr(id);i++)a[i]=v1; cover[id]=0; } int count(int l,int r,int v){ int res=0; for(int i=l;i<=r;i++){ if(a[i]==v)res++; else a[i]=v; } return res; } int get(int l,int r,int v){ if(cover[pos[l]]){ if(tag[pos[l]]==v)return r-l+1; else reset(pos[l],l,r,tag[pos[l]],v); } else return count(l,r,v); return 0; } int query(int l,int r,int v){ int res=get(l,min(findr(pos[l]),r),v); if(pos[l]!=pos[r])res+=get(findl(pos[r]),r,v); for(int i=pos[l]+1;i<=pos[r]-1;i++){ if(cover[i]){ if(tag[i]==v)res+=pos[l]==pos[n]?m:block; else tag[i]=v; } else { res+=count(findl(i),findr(i),v); cover[i]=1; tag[i]=v; } } return res; } int main(){ scanf("%d",&n); block=sqrt(n); for(int i=1;i<=n;i++){ pos[i]=(i-1)/block+1; scanf("%d",&a[i]); } m=n-(pos[n]-1)*block; int l,r,c; for(int i=1;i<=n;i++){ scanf("%d%d%d",&l,&r,&c); printf("%d\n",query(l,r,c)); } return 0; }