区间查询数值+整体赋值
维护tag代表整个区间被赋成了tag[i]
用pushdown操作,而不是修改了再check。
不压缩代码了,调起来心累,长点有啥不好。
//Stay foolish,stay hungry,stay young,stay simple
#include<iostream>
#include<cmath>
#include<cctype>
#include<cstdio>
using namespace std;
inline int read_d(){
int ret=0,f=1;char c;
while(c=getchar(),!isdigit(c)) f=c=='-'?-1:1;
while(isdigit(c)){
ret=ret*10+c-'0';
c=getchar();
}
return ret*f;
}
const int MAXN=500005;
int n;
int a[MAXN],l[MAXN],r[MAXN],tag[MAXN];
int bl[MAXN];
int num,block;
void pushdown(int id){
if(tag[id]==-1) return;
for(int i=l[id];i<=r[id];i++) a[i]=tag[id];
tag[id]=-1;
}
void build(){
block=sqrt(n);
num=n/block;
if(n%block) num++;
for(int i=1;i<=n;i++){
bl[i]=(i-1)/block+1;
}
for(int i=1;i<=num;i++){
l[i]=(i-1)*block+1;
r[i]=i*block;
tag[i]=-1;
}
r[num]=n;
}
int query(int x,int y,int w){
int ret=0;
if(bl[x]==bl[y]){
pushdown(bl[x]);
for(int i=x;i<=y;i++) ret+=(a[i]==w),a[i]=w;
return ret;
}
pushdown(bl[x]);
for(int i=x;i<=r[bl[x]];i++){
ret+=(a[i]==w);a[i]=w;
}
pushdown(bl[y]);
for(int i=l[bl[y]];i<=y;i++){
ret+=(a[i]==w);a[i]=w;
}
for(int i=bl[x]+1;i<=bl[y]-1;i++){
if(tag[i]==-1){
for(int j=l[i];j<=r[i];j++){
ret+=(a[j]==w);
a[j]=w;
}
tag[i]=w;
continue;
}
if(tag[i]==w){
ret+=r[i]-l[i]+1;
}else tag[i]=w;
}
return ret;
}
int main(){
n=read_d();
for(int i=1;i<=n;i++) a[i]=read_d();
build();
for(int i=1;i<=n;i++){
int x=read_d(),y=read_d(),z=read_d();
printf("%d
",query(x,y,z));
}
return 0;
}