题目描述
给出一个长为 nn 的数列,以及 nn 个操作,操作涉及区间询问等于一个数 cc 的元素,并将这个区间的所有元素改为 cc。
输入格式
第一行输入一个数字 nn。
第二行输入 nn 个数字,第 i 个数字为 a_iai,以空格隔开。
接下来输入 nn 行询问,每行输入三个数字 ll、rr、cc,以空格隔开。
表示先查询位于 [l,r][l,r] 的数字有多少个是 cc,再把位于 [l,r][l,r] 的数字都改为 cc。
输出格式
对于每次询问,输出一行一个数字表示答案。
样例
样例输入
4
1 2 2 4
1 3 1
1 4 4
1 2 2
1 4 2
样例输出
1
1
0
2
数据范围与提示
对于 100\%100% 的数据,1 leq n leq 100000, -2^{31} leq mathrm{others}1≤n≤100000,−231≤others、mathrm{ans} leq 2^{31}-1ans≤231−1。
代码:
1 //#6284. 数列分块入门 8-区间查询等于一个数c的元素,并将这个区间的所有元素改为c 2 #include<bits/stdc++.h> 3 using namespace std; 4 typedef long long ll; 5 const int maxn=1e6+10; 6 7 int n,m; 8 int a[maxn],pos[maxn],tag[maxn]; 9 10 int Find(int l,int r,int c) 11 { 12 int num=0; 13 if(pos[l]==pos[r]){ 14 if(tag[pos[l]]==c) num+=r-l+1; 15 else{ 16 if(tag[pos[l]]!=-1){ 17 for(int i=(pos[l]-1)*m+1;i<=pos[l]*m;i++) 18 a[i]=tag[pos[l]]; 19 } 20 for(int i=l;i<=r;i++){ 21 if(a[i]==c) num++; 22 else a[i]=c; 23 } 24 int flag=0; 25 for(int i=(pos[l]-1)*m+1;i<=pos[l]*m;i++){ 26 if(a[i]!=c){ 27 flag=1;break; 28 } 29 } 30 if(!flag) tag[pos[l]]=c; 31 else tag[pos[l]]=-1; 32 } 33 } 34 else{ 35 if(tag[pos[l]]==c){ 36 num+=pos[l]*m-l+1; 37 } 38 else{ 39 if(tag[pos[l]]!=-1){ 40 for(int i=(pos[l]-1)*m+1;i<=pos[l]*m;i++) 41 a[i]=tag[pos[l]]; 42 } 43 for(int i=l;i<=pos[l]*m;i++){ 44 if(a[i]==c) num++; 45 else a[i]=c; 46 } 47 int flag=0; 48 for(int i=(pos[l]-1)*m+1;i<=pos[l]*m;i++){ 49 if(a[i]!=c){ 50 flag=1;break; 51 } 52 } 53 if(!flag) tag[pos[l]]=c; 54 else tag[pos[l]]=-1; 55 } 56 for(int i=pos[l]+1;i<pos[r];i++){ 57 if(tag[i]==c) num+=m; 58 else{ 59 if(tag[i]!=-1) tag[i]=c; 60 else{ 61 for(int j=(i-1)*m+1;j<=i*m;j++){ 62 if(a[j]==c) num++; 63 else a[j]=c; 64 } 65 int flag=0; 66 for(int j=(i-1)*m+1;j<=i*m;j++){ 67 if(a[j]!=c){ 68 flag=1;break; 69 } 70 } 71 if(!flag) tag[i]=c; 72 else tag[i]=-1; 73 } 74 } 75 } 76 if(tag[pos[r]]==c) num+=r-((pos[r]-1)*m+1)+1; 77 else{ 78 if(tag[pos[r]]!=-1){ 79 for(int i=(pos[r]-1)*m+1;i<=min(pos[r]*m,n);i++){ 80 a[i]=tag[pos[r]]; 81 } 82 } 83 for(int i=(pos[r]-1)*m+1;i<=r;i++){ 84 if(a[i]==c) num++; 85 else a[i]=c; 86 } 87 int flag=0; 88 for(int i=(pos[r]-1)*m+1;i<=min(pos[r]*m,n);i++){ 89 if(a[i]!=c){ 90 flag=1;break; 91 } 92 } 93 if(!flag) tag[pos[r]]=c; 94 else tag[pos[r]]=-1; 95 } 96 } 97 return num; 98 } 99 100 int main() 101 { 102 scanf("%d",&n); 103 m=sqrt(n); 104 for(int i=1;i<=n;i++){ 105 scanf("%d",&a[i]); 106 pos[i]=(i-1)/m+1; 107 } 108 memset(tag,-1,sizeof(tag)); 109 for(int i=1;i<=n;i++){ 110 int l,r,c; 111 scanf("%d%d%d",&l,&r,&c); 112 printf("%d ",Find(l,r,c)); 113 } 114 } 115 116 117 /* 118 10 119 1 3 4 2 5 7 11 3 5 1 120 1 2 1 121 2 4 2 122 3 5 3 123 4 6 4 124 5 9 4 125 3 5 1 126 7 9 4 127 5 9 4 128 3 7 2 129 5 6 2 130 131 1 132 1 133 0 134 0 135 2 136 0 137 3 138 4 139 0 140 2 141 142 */