LGP2801 [] 教主的魔法 学习笔记
LGP2801 [] 教主的魔法 学习笔记
题意简述
给定一个长为
做法解析
感觉这个区间内多少数大于
反思一下,如果我们对于每次询问都把整个询问区间拉出来排序,会有很多冗余的计算量:我们只关注这个区间内元素和
(图为分块排序的合理性)
因此,我们考虑把区间分成
这就是分块的思想:把序列分成若干块,对每一块维护一些信息,操作就变成了对若干整块的统一操作和对两段散块的暴力操作。
做区间加法时,我们对整块打
代码实现
实码棍哥
#include <bits/stdc++.h>
using namespace std;
namespace obasic{
template <typename _T>
void readi(_T &x){
_T k=1;x=0;char ch=getchar();
for(;!isdigit(ch);ch=getchar())if(ch=='-')k=-1;
for(;isdigit(ch);ch=getchar())x=(x<<3)+(x<<1)+ch-'0';
x*=k;return;
}
template <typename _T>
void writi(_T x){
if(x<0)putchar('-'),x=-x;
if(x>9)writi(x/10);
putchar(x%10+'0');
}
template <typename _T>
int pcedi(_T x,_T y){return (x-1)/y+1;}
};
using namespace obasic;
const int MaxN=1e6+5,MaxNr=1e3+5;
int N,M,Nr,A[MaxN],X,Y,Z;char Opt;
int bsiz,bnum,bel[MaxN],lb[MaxNr],rb[MaxNr];
int B[MaxN],tag[MaxNr];
void fmdf(int cl,int cr,int val){
int bl=bel[cl];
for(int i=cl;i<=cr;i++)A[i]+=val;
for(int i=lb[bl];i<=rb[bl];i++)B[i]=A[i];
sort(B+lb[bl],B+rb[bl]+1);
}
void modify(int cl,int cr,int val){
int bl=bel[cl],br=bel[cr];
if(bl==br){fmdf(cl,cr,val);return;}
for(int i=bl+1;i<br;i++)tag[i]+=val;
fmdf(cl,rb[bl],val),fmdf(lb[br],cr,val);
}
int fqry(int cl,int cr,int val){
int bl=bel[cl],res=0;
for(int i=cl;i<=cr;i++)if(A[i]+tag[bl]>=val)res++;
return res;
}
int query(int cl,int cr,int val){
int bl=bel[cl],br=bel[cr],fres=0;
if(bl==br)return fqry(cl,cr,val);
int sl,sr,smid,sres;
for(int i=bl+1;i<br;i++){
sl=lb[i],sr=rb[i],sres=rb[i]+1;
while(sl<=sr){
smid=(sl+sr)>>1;
if(B[smid]+tag[i]>=val)sres=smid,sr=smid-1;
else sl=smid+1;
}
fres+=rb[i]-sres+1;
}
fres+=fqry(cl,rb[bl],val)+fqry(lb[br],cr,val);
return fres;
}
int main(){
readi(N),readi(M);
bsiz=sqrt(N),bnum=pcedi(N,bsiz);
for(int i=1;i<=bnum;i++)lb[i]=rb[i-1]+1,rb[i]=bsiz*i;
rb[bnum]=N;for(int i=1;i<=N;i++)bel[i]=pcedi(i,bsiz);
for(int i=1;i<=N;i++)readi(A[i]);
memcpy(B,A,sizeof(A));
for(int i=1;i<=bnum;i++)sort(B+lb[i],B+rb[i]+1);
for(int i=1;i<=M;i++){
scanf(" %c",&Opt);
readi(X),readi(Y),readi(Z);
if(Opt=='M')modify(X,Y,Z);
if(Opt=='A')writi(query(X,Y,Z)),puts("");
}
return 0;
}
反思总结
当你觉得某个序列上的某些操作太不可做的时候,想想根号,想想根号,想想根号!!!
想想根号,想想根号,想想根号!!!
标签:
分块
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 地球OL攻略 —— 某应届生求职总结
· 提示词工程——AI应用必不可少的技术
· Open-Sora 2.0 重磅开源!
· 周边上新:园子的第一款马克杯温暖上架