# 数列分块入门
#6277. 数列分块入门 1 - 题目 - LibreOJ
#include<bits/stdc++.h>
using namespace std;
const int N=5e4+10;
int n,a[N];
int bel[N],tot,block,l[N],r[N],tag[N];
void init(){
block=sqrt(n)+1;
tot=n/block;
if(n%block)tot++;
for(int i=1;i<=tot;++i){
l[i]=(i-1)*block+1;
r[i]=min(i*block,n);
}
for(int i=1;i<=n;++i)bel[i]=(i-1)/block+1;
}
void add(int x,int y,int c){
if(y-x<=block){
for(int i=x;i<=y;++i)a[i]+=c;
return ;
}
for(int i=x;i<=r[bel[x]];++i)a[i]+=c;
for(int i=l[bel[y]];i<=y;++i)a[i]+=c;
for(int i=bel[x]+1;i<bel[y];++i)tag[i]+=c;
}
int main(){
ios::sync_with_stdio(0),cin.tie(0);
cin>>n;
for(int i=1;i<=n;++i)cin>>a[i];
init();
for(int i=1;i<=n;++i){
int op,L,R,c;
cin>>op>>L>>R>>c;
if(op==0) add(L,R,c);
if(op==1) cout<<tag[bel[R]]+a[R]<<"\n";
}
return 0;
}
#6278. 数列分块入门 2 - 题目 - LibreOJ
#include<bits/stdc++.h>
using namespace std;
const int maxn=5e4+10;
int n,a[maxn+10];
vector<int>v[5010];
int bel[maxn+10],block,tot,sum[maxn+10],l[maxn+10],r[maxn+10];
void init(){
block=0.5*sqrt(n);
tot=n/block;if(n%block)tot++;
for(int i=1;i<=tot;++i){
l[i]=(i-1)*block+1;
r[i]=min(n,i*block);
}
for(int i=1;i<=n;++i) bel[i]=(i-1)/block+1 , v[bel[i]].push_back(a[i]);
for(int i=1;i<=bel[n];++i)sort(v[i].begin(),v[i].end());
}
void reset(int x){
v[x].clear();
for(int i=l[x];i<=r[x];++i)v[x].push_back(a[i]);
sort(v[x].begin(),v[x].end());
}
void add(int x,int y,int c){
for(int i=x;i<=min(y,r[bel[x]]);++i)a[i]+=c;
reset(bel[x]);
if(bel[x]!=bel[y]){
for(int i=l[bel[y]];i<=y;++i)a[i]+=c;
reset(bel[y]);
}
for(int i=bel[x]+1;i<bel[y];++i)sum[i]+=c;
}
int q(int x,int y,int c){
int cnt=0;
for(int i=x;i<=min(y,r[bel[x]]);++i) cnt+=(sum[bel[x]]+a[i]<c);
if(bel[x]!=bel[y]) for(int i=l[bel[y]];i<=y;++i) cnt+=(sum[bel[y]]+a[i]<c);
for(int i=bel[x]+1;i<bel[y];++i){
int tmp=c-sum[i];
cnt+=lower_bound(v[i].begin(),v[i].end(),tmp)-v[i].begin();
}
return cnt;
}
signed main(){
ios::sync_with_stdio(0),cin.tie(0);
cin>>n;
for(int i=1;i<=n;++i)cin>>a[i];
init();
for(int i=1;i<=n;++i){
int op,l,r,c;
cin>>op>>l>>r>>c;
if(op==0)add(l,r,c);
if(op==1)cout<<q(l,r,c*c)<<"\n";
}
return 0;
}
#6279. 数列分块入门 3 - 题目 - LibreOJ
#include<bits/stdc++.h>
using namespace std;
const int N=1e5+10;
int n,a[N];
int bel[N],tot,block,l[1000],r[1000],tag[1000];
vector<int>v[1000];
void init(){
block=sqrt(n)+1;
tot=n/block;
if(n%block)tot++;
for(int i=1;i<=tot;++i){
l[i]=(i-1)*block+1;
r[i]=min(i*block,n);
}
for(int i=1;i<=n;++i)bel[i]=(i-1)/block+1;
for(int i=1;i<=tot;++i){
for(int j=l[i];j<=r[i];++j) v[i].push_back(a[j]);
sort(v[i].begin(),v[i].end());
}
}
void reset(int blo){
v[blo].clear();
for(int i=l[blo];i<=r[blo];++i) v[blo].push_back(a[i]);
sort(v[blo].begin(),v[blo].end());
}
void add(int x,int y,int c){
if(y-x<=block){
for(int i=x;i<=y;++i)a[i]+=c;
reset(bel[x]);if(bel[x]!=bel[y])reset(bel[y]);
return ;
}
for(int i=x;i<=r[bel[x]];++i)a[i]+=c;
for(int i=l[bel[y]];i<=y;++i)a[i]+=c;
for(int i=bel[x]+1;i<bel[y];++i)tag[i]+=c;
reset(bel[x]);
if(bel[x]!=bel[y])reset(bel[y]);
}
int q(int x,int y,int c){
if(y-x<=block){
int ans=-INT_MAX;
for(int i=x;i<=y;++i){
if(a[i]+tag[bel[i]]>=c)continue;
ans=max(ans,a[i]+tag[bel[i]]);
}
if(ans==-INT_MAX)return -1;
return ans;
}
int ans=-INT_MAX;
for(int i=x;i<=r[bel[x]];++i){
if(a[i]+tag[bel[i]]>=c)continue;
ans=max(ans,a[i]+tag[bel[i]]);
}
for(int i=l[bel[y]];i<=y;++i){
if(a[i]+tag[bel[i]]>=c)continue;
ans=max(ans,a[i]+tag[bel[i]]);
}
for(int i=bel[x]+1;i<bel[y];++i){
int it=lower_bound(v[i].begin(),v[i].end(),c-tag[i])-v[i].begin();
it--;
if(it==-1)continue;
ans=max(ans,v[i][it]+tag[i]);
}
if(ans==-INT_MAX)return -1;
return ans;
}
int main(){
ios::sync_with_stdio(0),cin.tie(0);
cin>>n;
for(int i=1;i<=n;++i)cin>>a[i];
init();
for(int i=1;i<=n;++i){
int op,L,R,c;
cin>>op>>L>>R>>c;
if(op==0) add(L,R,c);
if(op==1) cout<<q(L,R,c)<<"\n";
}
return 0;
}
#6280. 数列分块入门 4 - 题目 - LibreOJ
#include<bits/stdc++.h>
using namespace std;
#define int long long
const int N=5e4+10;
int n,a[N];
int bel[N],tot,block,l[1000],r[1000],tag[1000],sum[1000];
void reset(int x){
sum[x]=0;
for(int i=l[x];i<=r[x];++i) sum[x]+=a[i];
}
void init(){
block=sqrt(n)+1;
tot=n/block;
if(n%block)tot++;
for(int i=1;i<=tot;++i){
l[i]=(i-1)*block+1;
r[i]=min(i*block,n);
}
for(int i=1;i<=n;++i)bel[i]=(i-1)/block+1;
for(int i=1;i<=tot;++i)reset(i);
}
void add(int x,int y,int c){
if(y-x<=block){
for(int i=x;i<=y;++i)a[i]+=c;
reset(bel[x]);if(bel[x]!=bel[y])reset(bel[y]);
return ;
}
for(int i=x;i<=r[bel[x]];++i)a[i]+=c;
for(int i=l[bel[y]];i<=y;++i)a[i]+=c;
for(int i=bel[x]+1;i<bel[y];++i)tag[i]+=c;
reset(bel[x]);
if(bel[x]!=bel[y])reset(bel[y]);
}
int q(int x,int y,int mod){
int sm=0;
if(y-x<=block){
for(int i=x;i<=y;++i)sm+=a[i]+tag[bel[i]],sm%=mod;
return sm%mod;
}
for(int i=x;i<=r[bel[x]];++i)sm+=a[i]+tag[bel[i]],sm%=mod;
for(int i=l[bel[y]];i<=y;++i)sm+=a[i]+tag[bel[i]],sm%=mod;
for(int i=bel[x]+1;i<bel[y];++i)sm+=block*tag[i]%mod+sum[i],sm%=mod;
return (sm%mod+mod)%mod;
}
signed main(){
ios::sync_with_stdio(0),cin.tie(0);
cin>>n;
for(int i=1;i<=n;++i)cin>>a[i];
init();
for(int i=1;i<=n;++i){
int op,L,R,c;
cin>>op>>L>>R>>c;
if(op==0) add(L,R,c);
if(op==1) cout<<q(L,R,c+1)<<"\n";
}
return 0;
}
#6281. 数列分块入门 5 - 题目 - LibreOJ
#include<bits/stdc++.h>
using namespace std;
#define int long long
const int N=5e4+10;
int n,a[N];
int bel[N],tot,block,l[N],r[N],tag[N],sum[1000],mx[1000];
int get(int tmp,int k){
if(tmp==1)return 1;
while(k--){
tmp=(int)sqrt(tmp);
if(tmp==1)return 1;
}return tmp;
}
void reset(int x){
sum[x]=0;
mx[x]=-INT_MAX;
for(int i=l[x];i<=r[x];++i){
a[i]=get(a[i],tag[x]);
sum[x]+=a[i];
mx[x]=max(mx[x],a[i]);
}
tag[x]=0;
}
void init(){
block=sqrt(n)+1;
tot=n/block;
if(n%block)tot++;
for(int i=1;i<=tot;++i){
l[i]=(i-1)*block+1;
r[i]=min(i*block,n);
}
for(int i=1;i<=n;++i){
bel[i]=(i-1)/block+1;
mx[bel[i]]=max(mx[bel[i]],a[i]);
}
for(int i=1;i<=tot;++i) reset(i);
}
void sq(int x,int y){
if(y-x<=block){
for(int i=x;i<=y;++i)a[i]=(int)sqrt(a[i]);
reset(bel[x]);if(bel[x]!=bel[y])reset(bel[y]);
return ;
}
for(int i=x;i<=r[bel[x]];++i)a[i]=(int)sqrt(a[i]);
for(int i=l[bel[y]];i<=y;++i)a[i]=(int)sqrt(a[i]);
for(int i=bel[x]+1;i<bel[y];++i)tag[i]++;
reset(bel[x]);if(bel[x]!=bel[y])reset(bel[y]);
}
int q(int x,int y){
if(y-x<=block){
int sm=0;
for(int i=x;i<=y;++i) sm+=get(a[i],tag[bel[i]]);
return sm;
}
int sm=0;
reset(bel[x]);if(bel[x]!=bel[y])reset(bel[y]);
for(int i=x;i<=r[bel[x]];++i)sm+=a[i];
for(int i=l[bel[y]];i<=y;++i)sm+=a[i];
for(int i=bel[x]+1;i<bel[y];++i){
if(tag[i]==0||mx[i]==1){
sm+=sum[i]; continue;
}
reset(i);
sm+=sum[i];
}
return sm;
}
signed main(){
ios::sync_with_stdio(0),cin.tie(0);
cin>>n;
for(int i=1;i<=n;++i)cin>>a[i];
init();
for(int i=1;i<=n;++i){
int op,L,R,c;
cin>>op>>L>>R>>c;
if(op==0) sq(L,R);
if(op==1) cout<<q(L,R)<<"\n";
}
return 0;
}
#6282. 数列分块入门 6 - 题目 - LibreOJ
#include<bits/stdc++.h>
using namespace std;
const int N=2e5+10;
int n,a[N];
int block,tot,bel[N],L[N],R[N],cnt=0;
vector<int>v[N],p;
void reset(){
p.clear();
for(int i=1;i<=tot;++i){
for(auto j:v[i]) p.push_back(j);
v[i].clear();
}
block=sqrt(p.size())+1;tot=p.size()/block;
if(p.size()%block)tot++;
for(int i=1;i<=n;++i){
bel[i]=(i-1)/block+1;
v[bel[i]].push_back(p[i-1]);
}
}
void init(){
cin>>n;cnt=n;
for(int i=1;i<=n;++i)cin>>a[i];
block=sqrt(n);tot=n/block;
if(n%block)tot++;
for(int i=1;i<=n;++i){
bel[i]=(i-1)/block+1;
v[bel[i]].push_back(a[i]);
}
}
void ins(int l,int r){
for(int i=1;i<=tot;++i){
if(v[i].size()<l){
l-=v[i].size();
continue;
}
v[i].insert(v[i].begin()+l-1,r);
break;
}
}
void find(int x){
for(int i=1;i<=tot;++i){
if(v[i].size()<x){
x-=v[i].size();
continue;
}
cout<<v[i][x-1]<<"\n";
break;
}
}
void debug(){
puts("\n");
for(int i=1;i<=tot;++i){
for(auto j:v[i])cout<<j<<" ";
}puts("\n");
}
bool check(){
for(int i=1;i<=tot;++i){
if(v[i].size()>4*sqrt(cnt))return 1;
}return 0;
}
int main(){
// ios::sync_with_stdio(0),cin.tie(0);
init();
for(int i=1;i<=n;++i){
int op,l,r,c;
cin>>op>>l>>r>>c;
if(op==0){
ins(l,r);
cnt++;
}
if(op==1){
find(r);
}
if(check())reset();
// debug();
}
return 0;
}
#6283. 数列分块入门 7 - 题目 - LibreOJ
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define int __int128
const int N=1e5+10,mod=10007;
ll n,a[N],bel[N],l[N],r[N],block,tot;
int t1[N],t2[N];
void reset(int x){
for(int i=l[x];i<=r[x];++i) a[i]=a[i]*t2[x]+t1[x],a[i]%=mod;
t2[x]=1; t1[x]=0;
}
void init()
{
cin>>n;
for(int i=1;i<=n;++i)cin>>a[i];
block=int(0.5*sqrt(n))+1;tot=n/block;
if(n%block)tot++;
for(ll i=1;i<=tot;++i){
l[i]=(i-1)*block+1;
r[i]=min(n,i*block);
t2[i]=1;
}
for(ll i=1;i<=n;++i){
bel[i]=(i-1)/block+1;
}
}
void add(int x,int y,int c){
reset(bel[x]);
if(bel[x]!=bel[y])reset(bel[y]);
if(y-x<=block){
for(int i=x;i<=y;++i){
a[i]+=c;
}
return ;
}
for(int i=x;i<=r[bel[x]];++i){
a[i]+=c;
}
for(int i=l[bel[y]];i<=y;++i){
a[i]+=c;
}
for(int i=bel[x]+1;i<bel[y];++i){
t1[i]+=c;
}
}
void mul(int x,int y,int c){
reset(bel[x]);
if(bel[x]!=bel[y])reset(bel[y]);
if(y-x<=block){
for(int i=x;i<=y;++i){
a[i]*=c;
a[i]%=mod;
}
return ;
}
for(int i=x;i<=r[bel[x]];++i){
a[i]*=c;
a[i]%=mod;
}
for(int i=l[bel[y]];i<=y;++i){
a[i]*=c;
a[i]%=mod;
}
for(int i=bel[x]+1;i<bel[y];++i){
t1[i]*=c;
t2[i]*=c;
t2[i]%=mod;
t1[i]%=mod;
}
}
void q(int x){
cout<<(ll)((a[x]*t2[bel[x]]%mod+t1[bel[x]]%mod)%mod)<<"\n";
}
signed main(){
ios::sync_with_stdio(0),cin.tie(0);
init();
for(int i=1;i<=n;++i){
ll op,L,R,c;
cin>>op>>L>>R>>c;
if(op==0){
add(L,R,c);
}
if(op==1){
mul(L,R,c);
}
if(op==2){
q(R);
}
}
return 0;
}
/*
ans[i]= a[i]*t2[i]+t1[i]
*/
#6284. 数列分块入门 8 - 题目 - LibreOJ
#include<bits/stdc++.h>
using namespace std;
#define int long long
const int N=1e5+10,inf=-LLONG_MAX;
int n,a[N];
int block,tot,l[N],r[N],bel[N],tag[N];
void init(){
cin>>n;
for(int i=1;i<=n;++i)cin>>a[i];
block=sqrt(n)+1;
tot=n/block;
if(n%block)tot++;
for(int i=1;i<=tot;++i){
l[i]=(i-1)*block+1;
r[i]=min(i*block,n);
tag[i]=inf;
}
for(int i=1;i<=n;++i) bel[i]=(i-1)/block+1;
}
void reset(int x){
if(tag[x]==inf)return ;
for(int i=l[x];i<=r[x];++i){
a[i]=tag[x];
}
tag[x]=inf;
}
int q(int x,int y,int c){
reset(bel[x]);
if(bel[x]!=bel[y])reset(bel[y]);
if(y-x<=block){
int cnt=0;
for(int i=x;i<=y;++i){
if(a[i]==c)cnt++;
a[i]=c;
}
return cnt;
}
int cnt=0;
for(int i=x;i<=r[bel[x]];++i){
if(a[i]==c)cnt++;
a[i]=c;
}
for(int i=l[bel[y]];i<=y;++i){
if(a[i]==c)cnt++;
a[i]=c;
}
for(int i=bel[x]+1;i<bel[y];++i){
if(tag[i]==c)cnt+=block;
else if(tag[i]==inf){
for(int j=l[i];j<=r[i];++j)cnt+=(a[j]==c);
}
tag[i]=c;
}
return cnt;
}
signed main(){
ios::sync_with_stdio(0),cin.tie(0);
init();
for(int i=1;i<=n;++i){
int op,L,R,c;
cin>>L>>R>>c;
cout<<q(L,R,c)<<"\n";
}
return 0;
}
#6285. 数列分块入门 9 - 题目 - LibreOJ
#include<bits/stdc++.h>
using namespace std;
#define int long long
const int N=1e5+10,M=5e4+10;
int n,m,X,A[N]/*原a_i*/,tmp[N],a[N]/*离散化后编号*/,t[N]/*编号对应的值*/,len;
int cnt[1403][N]/*某个数出现次数对块前缀和*/,tcnt[N],block,tot,bel[N],mr[1402][1402]/*块内众数*/,l[1402],r[1402];
void init(){
cin>>n;
for(int i=1;i<=n;++i)cin>>A[i],tmp[i]=A[i];
sort(tmp+1,tmp+1+n);
len=unique(tmp+1,tmp+1+n)-(tmp+1);//不同元素个数
for(int i=1;i<=n;++i) a[i]=lower_bound(tmp+1,tmp+len+1,A[i])-tmp,t[a[i]]=A[i];
block=(int)(sqrt(n))+1;
tot=n/block;if(n%block)tot++;
for(int i=1;i<=n;++i){
bel[i]=(i-1)/block+1;
}
for(int i=1;i<=tot;++i){
l[i]=(i-1)*block+1;
r[i]=min(i*block,n);
for(int j=l[i];j<=r[i];++j) cnt[i][a[j]]++;
}
for(int j=1;j<=tot;++j)
for(int i=1;i<=len;++i)
cnt[j][i]+=cnt[j-1][i];
for(int i=1;i<=tot;++i){
for(int j=1;j<=len;++j)tcnt[j]=0;
for(int j=i;j<=tot;++j){
mr[i][j]=mr[i][j-1];
for(int k=l[j];k<=r[j];++k) {
tcnt[a[k]]++;
if(tcnt[mr[i][j]]<tcnt[a[k]])mr[i][j]=a[k];
else if(tcnt[mr[i][j]]==tcnt[a[k]]){if(mr[i][j]>a[k])mr[i][j]=a[k];}
}
}
}
}
void q(int x,int y){
if(y-x<=block){
for(int i=x;i<=y;++i) tcnt[a[i]]=0;
for(int i=x;i<=y;++i) tcnt[a[i]]++;
int ans=a[x];
for(int i=x;i<=y;++i){
if(tcnt[ans]<tcnt[a[i]])ans=a[i];
else if(tcnt[ans]==tcnt[a[i]]) {if(ans>a[i])ans=a[i];}
}
cout<<(X=t[ans])<<"\n";
return ;
}
for(int i=x;i<=r[bel[x]];++i) tcnt[a[i]]=cnt[bel[y]-1][a[i]]-cnt[bel[x]][a[i]];
for(int i=l[bel[y]];i<=y;++i) tcnt[a[i]]=cnt[bel[y]-1][a[i]]-cnt[bel[x]][a[i]];
tcnt[mr[bel[x]+1][bel[y]-1]]= cnt[bel[y]-1][mr[bel[x]+1][bel[y]-1]] -cnt[bel[x]][mr[bel[x]+1][bel[y]-1]];
for(int i=x;i<=r[bel[x]];++i) tcnt[a[i]]++;
for(int i=l[bel[y]];i<=y;++i) tcnt[a[i]]++;
int ans=a[x];
for(int i=x;i<=r[bel[x]];++i){
if(tcnt[ans]<tcnt[a[i]])ans=a[i];
else if(tcnt[ans]==tcnt[a[i]]) {if(ans>a[i])ans=a[i];}
}
for(int i=l[bel[y]];i<=y;++i){
if(tcnt[ans]<tcnt[a[i]])ans=a[i];
else if(tcnt[ans]==tcnt[a[i]]) {if(ans>a[i])ans=a[i];}
}
if(bel[x]+1<=bel[y]-1){
if(tcnt[ans]<tcnt[mr[bel[x]+1][bel[y]-1]])ans=mr[bel[x]+1][bel[y]-1];
else if(tcnt[ans]==tcnt[mr[bel[x]+1][bel[y]-1]]) {if(ans>mr[bel[x]+1][bel[y]-1])ans=mr[bel[x]+1][bel[y]-1];}
}
cout<<(X=t[ans])<<"\n";return;
}
signed main(){
ios::sync_with_stdio(0),cin.tie(0);
init();
for(int i=1;i<=n;++i)
{
int L,R;
cin>>L>>R;
q(L,R);
}
return 0;
}

浙公网安备 33010602011771号