LOJ #6284. 数列分块入门 8-分块(区间查询等于一个数c的元素,并将这个区间的所有元素改为c)

内存限制:256 MiB时间限制:500 ms标准输入输出
题目类型:传统评测方式:文本比较
上传者: hzwer

题目描述

给出一个长为 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}1n100000,231others、mathrm{ans} leq 2^{31}-1ans2311。

代码:

  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 */
原文地址:https://www.cnblogs.com/ZERO-/p/10525780.html