首页 > 其他分享 >#莫队二次离线,根号分治#洛谷 5398 [Ynoi2018] GOSICK

#莫队二次离线,根号分治#洛谷 5398 [Ynoi2018] GOSICK

时间:2024-04-10 22:24:13浏览次数:18  
标签:Ynoi2018 int 离线 个数 hs Et include 莫队 根号

题目

\(m\) 组询问求 \(\sum_{l\leq i,j\leq r}[a_i\bmod a_j==0],n,m,a_i\leq 5\times 10^5\)


分析

设 \(f(l,r,x)\) 表示 \(i 或 j\in [1,x],i或j\in [l,r]\) 时 的答案,\(g_x\) 表示 \([1,x]\) 的答案,根号的做法可以通过三秒

由于涉及区间内的求值,需要在莫队的基础上二次离线,那么从 \([l,r]\) 的答案扩展到 \([l,r']\) 就要加上 \(g(r')-g(r)-f(r+1,r',l-1)\)

从 \([l,r]\) 扩展到 \([l',r]\) 就要加上 \(f(l',l-1,r)-[g(l-1)-g(l'-1)]\),现在就是要求 f 和 g,后者可以通过前缀和实现

如果 \([l,r]\) 是作为因数,那么直接将 \(a_{1\sim x}\) 的因数统计个数,以 \(x\) 为第一关键字,即可做到 \(O(m\sqrt{n})\)

如果作为倍数,那么 \(a_{1\sim x}\) 中大于阈值的直接枚举倍数统计个数,小于等于的就要单独抽离出来,倘若现在枚举到 \(z\)

设 \(c_i\) 表示前 \(i\) 个数中 \(z\) 的倍数的个数,那么区间的答案就可以转化成前 \(x\) 个数中 \(z\) 的个数乘上 \(c_r-c_{l-1}\)

然后莫队的块长调到 \(1.5\sqrt{n}\),阈值调到 \(0.15\sqrt{\max\{a_i\}}\) 就可以过了,注意求 \(g_i\) 的时候要给每个位置减一,

因为 \((i,i)\) 和 \((i,i)\) 等价,但 \((i,j)\) 和 \((j,i)\) 在 \(a_i=a_j\) 时不等价


代码

#include <cstdio>
#include <cctype>
#include <cmath>
#include <algorithm>
#define getchar() (p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin)),p1==p2?EOF:*p1++)
using namespace std;
const int N=500011; char buf[1<<21],puf[1<<21],*p1,*p2; int nowp=-1;
struct rec{int l,r,rk;}q[N];
struct node{int y,next;}e[N*27];
struct Node{int x,y,rk,z,next;}E[N<<1];
typedef long long lll; lll s[N],ans[N];
int n,Q,bl,c[N],pos[N],a[N],b[N],as[N],bs[N],hs[N],rk[N],et,Et,m;
int iut(){
    int ans=0; char c=getchar();
    while (!isdigit(c)) c=getchar();
    while (isdigit(c)) ans=ans*10+c-48,c=getchar();
    return ans;
}
void Flush(){fwrite(puf,1,nowp+1,stdout),nowp=-1;}
void Putchar(char x){
	if (nowp==(1<<21)) Flush();
	puf[++nowp]=x;
}
void print(lll ans){
	char dig[21]; int len=-1;
	do{
		dig[++len]=ans%10+48,ans/=10;
	}while (ans);
	while (len>=0) Putchar(dig[len--]);
}
bool cmp(rec x,rec y){
    if (pos[x.l]!=pos[y.l]) return pos[x.l]<pos[y.l];
    return (pos[x.l]&1)?(x.r<y.r):(x.r>y.r);
}
int main(){
    n=iut(),Q=iut(),bl=sqrt(n)*1.5;
    for (int i=1;i<=n;++i) b[i]=a[i]=iut(),pos[i]=(i-1)/bl+1;
    for (int i=1;i<=Q;++i) q[i]=(rec){iut(),iut(),i};
    sort(q+1,q+1+Q,cmp);
    sort(b+1,b+1+n),m=unique(b+1,b+1+n)-b-1;
	bl=sqrt(m)*0.15+1;
    for (int i=1;i<=m;++i) rk[b[i]]=i;
    for (int i=1;i<=n;++i) a[i]=rk[a[i]];
    for (int i=1;i<=m;++i)
    for (int j=b[i];j<=b[m];j+=b[i])
    if (rk[j]){
        e[++et]=(node){rk[j],as[i]},as[i]=et;
        e[++et]=(node){i,bs[rk[j]]},bs[rk[j]]=et;
    }
    int L=q[1].l,R=q[1].l-1;
    for (int i=1;i<=Q;++i){
        if (L>q[i].l) E[++Et]=(Node){q[i].l,L-1,q[i].rk,1,hs[R]},hs[R]=Et,L=q[i].l;
        if (L<q[i].l) E[++Et]=(Node){L,q[i].l-1,q[i].rk,-1,hs[R]},hs[R]=Et,L=q[i].l;
        if (R>q[i].r) E[++Et]=(Node){q[i].r+1,R,q[i].rk,1,hs[L-1]},hs[L-1]=Et,R=q[i].r;
        if (R<q[i].r) E[++Et]=(Node){R+1,q[i].r,q[i].rk,-1,hs[L-1]},hs[L-1]=Et,R=q[i].r;
    }
    for (int i=1;i<=bl;++i){
        for (int j=1;j<=n;++j)
        if (b[a[j]]%b[i]==0) c[j]=c[j-1]+1;
            else c[j]=c[j-1];
		int now=0;
        for (int j=1;j<=n;++j){
            if (a[j]==i) ++now;
            if (b[a[j]]%b[i]==0) s[j]+=now;
            for (int k=hs[j];k;k=E[k].next)
                ans[E[k].rk]+=(c[E[k].y]-c[E[k].x-1])*now*E[k].z;
        }
    }
    for (int i=1;i<=n;++i) c[i]=0;
    for (int i=1;i<=n;++i){
        for (int j=bs[a[i]];j;j=e[j].next) ++c[e[j].y];
        if (a[i]>bl) for (int j=as[a[i]];j;j=e[j].next) ++c[e[j].y];
        s[i]+=c[a[i]]-1;
        for (int j=hs[i];j;j=E[j].next){
        	int now=0;
        	for (int k=E[j].x;k<=E[j].y;++k)
        	    now+=c[a[k]];
        	ans[E[j].rk]+=now*E[j].z;
		}
    }
    for (int i=1;i<=n;++i) s[i]+=s[i-1];
    for (int i=1;i<=Et;++i) ans[E[i].rk]-=E[i].z*(s[E[i].y]-s[E[i].x-1]);
    for (int i=1;i<=Q;++i) ans[q[i].rk]+=ans[q[i-1].rk];
    for (int i=1;i<=Q;++i) print(ans[i]),Putchar(10);
    Flush();
    return 0;
}

标签:Ynoi2018,int,离线,个数,hs,Et,include,莫队,根号
From: https://www.cnblogs.com/Spare-No-Effort/p/18127621

相关文章

  • Uniapp 打包流程 之离线打包
    Uniapp打包流程一、离线打包需要的工具:AndroidStudio,HBuilderX1.下载uniapp安卓打包所需要的SDK,下载地址:https://nativesupport.dcloud.net.cn/AppDocs/usesdk/android2下载完成后解压至相应文件夹,打开androidstudio,选择导入项目HBuilder-Hello;3.导入项目后,如......
  • power shell命令提供了对离线Windows映像进行管理和操作的功能,包括挂载、卸载、修改属
    以下是一些用于管理离线映像的PowerShell命令:Mount-WindowsImage:用于将Windows映像文件挂载到指定的目录以进行修改。powershellCopyCodeMount-WindowsImage-ImagePath"C:\path\to\image.wim"-Path"C:\path\to\mount"-Index1Dismount-WindowsImage:用于卸载之前......
  • docker离线部署Springboot项目
    首先先准备好项目jar包和Dockfile文件Dockfile文件配置如下:点击查看代码#拉取基础镜像FROMopenjdk:11#类似于作者MAINTAINERdpf#创建镜像目录RUNmkdir-p/htht/server/logs\/htht/server/temp\/htht/skywalking/agent#工作区WORKDIR/htht/server......
  • 百度驾驶证C++离线SDK V1.1 C#接入
    百度驾驶证C++离线SDKV1.1C#接入目录说明 效果 项目代码下载 说明 自己根据SDK封装了动态库,然后C#调用。SDK包结构效果 项目代码usingNewtonsoft.Json;usingOpenCvSharp;usingSystem;usingSystem.Collections.Generic;usingSystem.Diagnosti......
  • 在centos上离线安装k8s
    测试环境中很多是没有连外网的,在这种环境下安装k8s相对麻烦一点,本篇展示一下如何在没有外网的环境当中安装k8s。为了在离线环境当中安装,需要额外准备一台可以连接外网的机器,且这台机器可以向离线机器传输文件,以下称之为外网机器。安装k8s大致分为两步,安装binary文件包括kubectl,k......
  • Nginx离线配置ssl证书
    纯离线的内网环境中使用nginx配置ssl并使用https访问网站。对于服务器中nginx及其它环境的搭建,可参考我的该文章LinuxCentos7离线部署SpringBoot前后端分离项目同时,该文章涉及的部分安装包已提供在以上文章的开头部分。检查环境进入nginx的安装目录(一般是/usr/lo......
  • OpenStack离线安装系列0:制作yum源
    OpenStack离线安装系列0:制作yum源如果采用离线源代码安装,则通常需要配置本地pip源;如果采用离线软件安装包的形式安装,则通常需要配置本地yum源。环境说明系统:Centos7版本:CentOS-7-x86_64-Minimal-1908ISO下载链接:http://mirrors.aliyun.com/centos/7/isos/x86_64/CentOS-......
  • B站、微博视频批量下载,轻松实现离线观看!
    在现代社会,信息的传播和获取变得尤为重要。特别是对于那些热衷于在视频平台学习新知识、探索未知领域的人来说,能够随时随地下载这些平台的视频内容,以便在没有网络的情况下也能继续学习,无疑是提高效率的一大助力。现在小编就为大家演示下如何获取吧!1、我们需要准备一个工具“......
  • #离线,线段树#SP1557 GSS2 - Can you answer these queries II
    题目给定大小为\(n\)的序列,\(q\)次询问,求最大子段和,相同的数只算一次。选出的子段可以为空。分析数字不重复很难做,考虑离线,询问区间按右端点排序枚举区间右端点,不重复就相当于给\([pre+1,i]\)为开头的区间后添加\(a_i\)那么相当于维护以\(j\)为开头的最大子段和,以......
  • 离线数仓(九)【DWS 层开发】
    前言    上一个DWD层用了半个月时间,但是慢有慢的好处;今天开始DWS层的学习,目标是4月初把项目完成,完了赶紧从头回顾一遍项目。    今天操场跑了20分钟,顺便在这里记录一下,现在每周只有没早八的时候能跑一下了,近一年没有好好跑步了,这个习惯应该找回来了......