首页 > 其他分享 >莫队学习

莫队学习

时间:2023-07-21 15:35:53浏览次数:30  
标签:int belong 学习 while cnt1 time now 莫队

大致思路:
1.分块

2.对提问排序

3.暴力处理


# 莫队模板
```cpp
#include<bits/stdc++.h>
using namespace std;
const int N=1e6+10,M=1e6+10;
int a[N],belong[N],bnum,cnt[N];
int n,q,len,ans[M];
struct node
{
int l,r,id;
}e[M];
bool cmp(node a,node b)
{
return (belong[a.l]^belong[b.l])?belong[a.l]<belong[b.l]:((belong[a.l]&1)?a.r<b.r: a.r>b.r);
}
void solve()
{
scanf("%d",&n);
len=sqrt(n);
bnum=ceil((double)n/len);

for(int i=1;i<=bnum;i++)
for(int j=(i-1)*len+1;j<=i*len;j++)
belong[j]=i;

for(int i=1;i<=n;i++) scanf("%d",&a[i]);
scanf("%d",&q);

for(int i=1;i<=q;i++)
{
int id=i;
int l,r;
scanf("%d%d",&l,&r);
e[i]={l,r,id};
}
sort(e+1,e+q+1,cmp);
int l=1,r=0;
int now=0;
for(int i=1;i<=q;i++)
{
int ql=e[i].l,qr=e[i].r;
while(l<ql) now-=!--cnt[a[l++]];
while(l>ql) now+=!cnt[a[--l]]++;
while(r<qr) now+=!cnt[a[++r]]++;
while(r>qr) now-=!--cnt[a[r--]];
ans[e[i].id]=now;
}
for(int i=1;i<=q;i++) printf("%d\n",ans[i]);
}
int main()
{
solve();
return 0;
}

 

```
# 带修莫队

带修莫队学习

1.定义时间戳,多了往回跳,少了往后跳

2.排序最后一个关键字改为时间戳

3.注意常数大小,尽量使用快读

4.块长改为n的2/3次方

```cpp
#include<bits/stdc++.h>
using namespace std;
const int N=2e6+10,M=2e5+10;
int a[M],cnt[N],ans[M];
int len,bnum,belong[M];
int n,q,cnt1,cnt2;
inline int read()
{
char c=getchar();int x=0,f=1;
while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
while(c>='0'&&c<='9'){x=x*10+c-'0',c=getchar();}
return x*f;
}
inline void write(int x)
{
if(x<0){putchar('-');x=-x;}
if(x>9)write(x/10);
putchar(x%10+'0');
}
struct node
{
int l,r,time,id;
}e[M];
struct query
{
int pos,col;
}ch[M];
int cmp(node a, node b)
{
return (belong[a.l] ^ belong[b.l]) ? belong[a.l] < belong[b.l] : ((belong[a.r] ^ belong[b.r]) ? belong[a.r] < belong[b.r] : a.time < b.time);
}
void init()
{
n=read(),q=read();

for(int i=1;i<=n;i++) a[i]=read();

for(int i=1;i<=q;i++)
{
char op[100];
int l,r;
scanf("%s",op);
if(op[0]=='Q')
{
e[++cnt1].l=read();
e[cnt1].r=read();
e[cnt1].time=cnt2;
e[cnt1].id=cnt1;
}
else
{
ch[++cnt2].pos=read();
ch[cnt2].col=read();
}
}

len=pow(n,2.0/3.0);

bnum=ceil((double)n/len);

for(int i=1;i<=n;i++) belong[i]=(i-1)/len+1;

sort(e+1,e+cnt1+1,cmp);
}
void solve()
{
int time=0,now=0,l=1,r=0;
for(int i=1;i<=cnt1;i++)
{
int ql=e[i].l,qr=e[i].r,qt=e[i].time;
while(l<ql) now-=!--cnt[a[l++]];
while(l>ql) now+=!cnt[a[--l]]++;
while(r<qr) now+=!cnt[a[++r]]++;
while(r>qr) now-=!--cnt[a[r--]];

while(time<qt)
{
++time;
if(ql<=ch[time].pos&&ch[time].pos<=qr)
now-=!--cnt[a[ch[time].pos]]-!cnt[ch[time].col]++;
swap(a[ch[time].pos],ch[time].col);
}

while(time>qt)
{
if(ql<=ch[time].pos&&ch[time].pos<=qr)
now-=!--cnt[a[ch[time].pos]]-!cnt[ch[time].col]++;
swap(a[ch[time].pos],ch[time].col);
--time;
}
ans[e[i].id]=now;
}

for(int i=1;i<=cnt1;i++) printf("%d\n",ans[i]);
}
int main()
{
init();
solve();
return 0;
}
```
# 回滚莫队

应用的原因:

普通莫队带有删除操作,但有时(如区间最值)由于有删除,并不能很好维护
于是便产生此思想

1.按左端点所处块排序,若相同,则右端点递增排序

2.分块处理,若左右端点所处块相同,则暴力处理,此外,则左端点暴力处理,右端点依次递增,这样右端点维护信息为一段连续信息

3.及时备份保存信息(now值),及时清空数组(cnt)

4.每处理一个询问,左端点暴力回退,右端点继续递增,若端点处在同一块,处理外后及时continue

5.左端点初始位置为当前处理块最右段+1,右端点为最右端,类比普通莫队

```cpp
#include<bits/stdc++.h>
#define LL long long
using namespace std;
const int N=1e5+10,M=N*2;
int a[N],b[N],lb[N],rb[N],ty[N];
int n,q,len,belong[M],bnum;
int cnt1[N],cnt2[N];
LL ans[N];
struct node
{
int l,r,id;
}e[N];
inline int read()
{
int date=0,w=1;char c=0;
while(c<'0'||c>'9'){if(c=='-')w=-1;c=getchar();}
while(c>='0'&&c<='9'){date=date*10+c-'0';c=getchar();}
return date*w;
}
bool cmp(node a,node b)
{
return (belong[a.l]^belong[b.l])?belong[a.l]<belong[b.l]: a.r<b.r;
}
void init()
{
n=read(),q=read();
for(int i=1;i<=n;i++) a[i]=read(),b[i]=a[i];

len=sqrt(n);

bnum=ceil((double)n/len);

for(int i=1;i<=bnum;i++)
{
lb[i]=(i-1)*len+1;
rb[i]=i*len;
for(int j=lb[i];j<=rb[i];j++) belong[j]=i;
}

rb[bnum]=n;//最后一块可能长度不够,手动

for(int i=1;i<=q;i++)
{
int l,r;
l=read(),r=read();
e[i]={l,r,i};
}
sort(b+1,b+n+1);
sort(e+1,e+q+1,cmp);
int tot=unique(b+1,b+n+1)-b-1;
for(int i=1;i<=n;i++) ty[i]=lower_bound(b+1,b+tot+1,a[i])-b;
}
void solve()
{
int i=1;
for(int k=0;k<=bnum;k++)
{
int l=rb[k]+1,r=rb[k];
LL now=0;
memset(cnt1,0,sizeof(cnt1));
for(;belong[e[i].l]==k;i++)
{
int ql=e[i].l,qr=e[i].r;
LL tmp;
if(belong[ql]==belong[qr])
{
tmp=0;
for(int j=ql;j<=qr;j++) cnt2[ty[j]]=0;
for(int j=ql;j<=qr;j++)
{
++cnt2[ty[j]],tmp=max(tmp,1ll*cnt2[ty[j]]*a[j]);
}
ans[e[i].id]=tmp;
continue;
}
while(r<qr)
{
++cnt1[ty[++r]],now=max(now,1ll*cnt1[ty[r]]*a[r]);
}
tmp=now;
while(l>ql)
{
++cnt1[ty[--l]],now=max(now,1ll*cnt1[ty[l]]*a[l]);
}
ans[e[i].id]=now;
now=tmp;
while(l<rb[k]+1) --cnt1[ty[l++]];
}
}
for(int i=1;i<=q;i++) printf("%lld\n",ans[i]);
}
int main()
{
init();
solve();
return 0;
}

标签:int,belong,学习,while,cnt1,time,now,莫队
From: https://www.cnblogs.com/Emiliat/p/17571496.html

相关文章

  • FedR代码学习文档
    main.py参数设置,进入主函数if__name__=='__main__':parser=argparse.ArgumentParser()#parser.add_argument('--data_path',default='Fed_data/WN18RR-Fed3.pkl',type=str)parser.add_argument('--data_path',defa......
  • k8s 学习笔记之搭建 nginx 服务测试搭建的环境
    服务部署接下来在kubernetes集群中部署一个nginx基础程序,测试集群是否正常工作。#部署nginx[root@master~]#kubectlcreatedeploymentnginx--image=nginx:1.14-alpine#暴露端口[root@master~]#kubectlexposedeploymentnginx--port=80--type=NodePort#......
  • 《Language Model Cascades》论文学习
    一、Introduction语言模型(LM)已展现出令人印象深刻的小样本学习能力,很多人建议应该将LM视为一个基础通用推理计算器,这个基础通用推理计算器可以被用于例如:scratchpadschainofthoughtpromptinglearnedverifiersselection-inferencebootstrappingbeenappliedinfor......
  • springboot学习之十三(druid+mybaits plus)
    Druid介绍Druid是阿里巴巴的一个开源项目,号称为监控而生的数据库连接池,在功能、性能、扩展性方面都超过其他例如DBCP、C3P0、BoneCP、Proxool、JBossDataSource等连接池,而且Druid已经在阿里巴巴部署了超过600个应用,通过了极为严格的考验,这才收获了大家的青睐! Springboot集成......
  • k8s 学习笔记之集群网络插件安装
    我们在安装完集群后,通过kubectlgetnodes命令获取节点,可以看到所有节点都处于NotReady的状态,这是没有安装网络插件导致的。安装网络插件kubernetes支持多种网络插件,比如flannel、calico、canal等等,任选一种使用即可,本次选择flannel下面操作只需在master节点执行即可,插件......
  • k8s 学习笔记之 centos7 环境初始化
    Linux环境初始化——CentOS7.9确保Linux版本在7.5以上,方便安装k8s集群,且所有机器上需要配置环境1.查看操作系统版本[root@master~]#cat/etc/redhat-releaseCentOSLinuxrelease7.9.2009(Core)2.主机名解析这里是为了方便集群节点之间的直接调用,可以配......
  • AJAX学习
    url统一资源定位符协议://域名/资源路径从服务器获取数据案例:根据输入省份城市名字查询市区 <scriptsrc="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script>   <script>     functionfn(){       letpName=document.querySel......
  • java学习day01
    Day01java笔记1.什么是程序程序:为了让计算机执行某些操作或者解决某个问题而编写的有序集合计算机语言(1)低级语言机器语言只认识01汇编语言(2)高级语言面向过程语言:c语言面向对象语言:java,python,c#等2.人机交互控制台常用命令:(1)切换盘符D:+回车(2)dir 查......
  • Golang中Gin框架开发学习记录——(一)
    1、环境配置    在GO语言中,使用"goget"命令获取相关包"goget"命令的作用与“gitclone”类似,这里使用:goget-ugithub.com/gin-gonic/gin来获取,相关代理问题可以参考以下链接:(19条消息)解决GO安装gin框架(goget-ugithub.com/gin-gonic/gin)超时问......
  • 学习生理基础 | 记忆的四个环节1——识记 | 2023年7月21日
    小虾米原创作品,转载请注明出处:https://www.cnblogs.com/shrimp-can/p/17570988.html 我们都想高效学习,但如何实现呢?网络上充斥着各种记忆、学习的技巧,能给予我们很大的帮助。但我始终认为,要做好一件事,须得“顺势而为”。那对于学习,什么是这个“势”呢?我认为便是人学习的生理......