#6284. 数列分块入门 8(区间询问等于一个数 cc 的元素,并将这个区间的所有元素改为 c)
题目链接:https://loj.ac/problem/6284
题目大意:中文题目
具体思路:还是和sqrt那个题的思路相同的,标记每一块的值是不是相同的,注意lazy下标的下放。
AC代码:
1 #include<bits/stdc++.h> 2 using namespace std; 3 # define ll long long 4 const int maxn = 2e6+100; 5 const int inf = 0x3f3f3f3f; 6 const int mod = 1e4+7; 7 ll l[maxn],r[maxn],belong[maxn]; 8 ll flag[maxn],a[maxn]; 9 int n; 10 void buildblock() 11 { 12 ll tmp=(ll)sqrt(n); 13 ll tot=n/tmp; 14 if(n%tmp) 15 tot++; 16 for(ll i=1; i<=n; i++) 17 { 18 belong[i]=(i-1)/tmp+1ll; 19 } 20 for(ll i=1; i<=tot; i++) 21 { 22 l[i]=(i-1)*tmp+1ll; 23 r[i]=i*tmp; 24 } 25 r[tot]=n; 26 } 27 void down(int pos) 28 { 29 if(flag[pos]==-1) 30 return ; 31 for(int i=l[pos]; i<=r[pos]; i++) 32 { 33 a[i]=flag[pos]; 34 } 35 flag[pos]=-1; 36 } 37 ll ask(ll st,ll ed,ll val) 38 { 39 int ans=0; 40 down(belong[st]); 41 if(belong[st]==belong[ed]) 42 { 43 for(int i=st; i<=ed; i++) 44 { 45 ans+=(a[i]==val?1:0); 46 a[i]=val; 47 } 48 return ans; 49 } 50 down(belong[st]); 51 for(int i=st; i<=r[belong[st]]; i++) 52 { 53 ans+=(a[i]==val?1:0); 54 a[i]=val; 55 } 56 down(belong[ed]); 57 for(int i=l[belong[ed]]; i<=ed; i++) 58 { 59 ans+=(a[i]==val?1:0); 60 a[i]=val; 61 } 62 for(int i=belong[st]+1; i<belong[ed]; i++) 63 { 64 if(flag[i]==-1){ 65 for(int j=l[i]; j<=r[i]; j++) 66 ans+=(a[j]==val?1:0); 67 } 68 else if(flag[i]==val){ 69 ans+=(r[i]-l[i]+1); 70 } 71 flag[i]=val; 72 } 73 return ans; 74 } 75 int main() 76 { 77 for(int i=0; i<=maxn; i++) 78 flag[i]=-1; 79 scanf("%d",&n); 80 for(int i=1; i<=n; i++) 81 scanf("%lld",&a[i]); 82 buildblock(); 83 ll st,ed,val; 84 while(n--) 85 { 86 scanf("%lld %lld %lld",&st,&ed,&val); 87 printf("%lld\n",ask(st,ed,val)); 88 } 89 return 0; 90 }