原题传送门

二次离线莫队

二次离线莫队的做法参考第十四分块(前体)的题解

我们需要考虑从(1,i)如何推到(1,i+1)

我们算过了a[i]的答案,考虑加入a[i]的贡献

我们需要在a[i]的所有约数上打标记,这个珂以直接暴力(因为约数是\(\sqrt n\)级别的)

我们还要考虑倍数的问题,当a[i]>32时,直接暴力更新倍数打标记;a[i]<=32时,设计一个状态s[1……32],每位1表示有这个约数,0表示没有这个约数,因为一共232个状态过多,所以每8个拆成一位,变成4个28=256状态,我们需要在0~255中第a[i]%8位为1的状态打标记即可

说的有可能不清楚,放一下代码

inline void update(register int x)
{
for(register int i=0;i<tot[x];++i)
++bs[fac[x][i]];
if(x<=32)
{
if(x<=8)
{
for(register int s=0;s<256;++s)
if(s>>(x-1)&1)
++s1[s];
}
else if(x<=16)
{
for(register int s=0;s<256;++s)
if(s>>(x-9)&1)
++s2[s];
}
else if(x<=24)
{
for(register int s=0;s<256;++s)
if(s>>(x-17)&1)
++s3[s];
}
else
{
for(register int s=0;s<256;++s)
if(s>>(x-25)&1)
++s4[s];
}
}
else
for(register int i=x;i<=100000;i+=x)
++ys[i];
}

我们考虑a[i+1]的答案,答案就是约数标记、倍数标记和状压标记之和。状压标记要单独计算(如下),c[x]就是一个长为32位的状态,表示x是否有1~32的约数

inline int calc(register unsigned int x)
{
x=c[x];
return s1[x&255]+s2[x>>8&255]+s3[x>>16&255]+s4[x>>24];
}

完整代码(有些我可能说不清,珂以结合代码理解)

#include <bits/stdc++.h>
#define N 100005
#define ll long long
#define getchar nc
using namespace std;
inline char nc(){
static char buf[100000],*p1=buf,*p2=buf;
return p1==p2&&(p2=(p1=buf)+fread(buf,1,100000,stdin),p1==p2)?EOF:*p1++;
}
inline int read()
{
register int x=0,f=1;register char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9')x=(x<<3)+(x<<1)+ch-'0',ch=getchar();
return x*f;
}
inline void write(register ll x)
{
if(!x)putchar('0');if(x<0)x=-x,putchar('-');
static int sta[20];register int tot=0;
while(x)sta[tot++]=x%10,x/=10;
while(tot)putchar(sta[--tot]+48);
}
int n,m,a[N],blocksize,s1[256],s2[256],s3[256],s4[256];
struct query{
int l,r,id,bl;
}q[N];
inline bool cmp(register query a,register query b)
{
return a.bl!=b.bl?a.l<b.l:((a.bl&1)?a.r<b.r:a.r>b.r);
}
int fac[N][200],tot[N],ys[N],bs[N];
unsigned int c[N];
ll pres[N],sufs[N],ans[N],res[N];
struct node{
int l,r,id,op;
};
vector<node> L[N],R[N];
inline int calc(register unsigned int x)
{
x=c[x];
return s1[x&255]+s2[x>>8&255]+s3[x>>16&255]+s4[x>>24];
}
inline void update(register int x)
{
for(register int i=0;i<tot[x];++i)
++ys[fac[x][i]];
if(x<=32)
{
if(x<=8)
{
for(register int s=0;s<256;++s)
if(s>>(x-1)&1)
++s1[s];
}
else if(x<=16)
{
for(register int s=0;s<256;++s)
if(s>>(x-9)&1)
++s2[s];
}
else if(x<=24)
{
for(register int s=0;s<256;++s)
if(s>>(x-17)&1)
++s3[s];
}
else
{
for(register int s=0;s<256;++s)
if(s>>(x-25)&1)
++s4[s];
}
}
else
for(register int i=x;i<=100000;i+=x)
++bs[i];
}
inline void clear()
{
memset(s1,0,sizeof(s1));
memset(s2,0,sizeof(s2));
memset(s3,0,sizeof(s3));
memset(s4,0,sizeof(s4));
memset(ys,0,sizeof(ys));
memset(bs,0,sizeof(bs));
}
int main()
{
for(register int i=1;i<=100000;++i)
{
for(register int j=i;j<=100000;j+=i)
fac[j][tot[j]++]=i;
if(i<=32)
for(register int j=i;j<=100000;j+=i)
c[j]|=1u<<i-1;
}
n=read(),m=read();
blocksize=n/(sqrt(m*2/3)+1);
for(register int i=1;i<=n;++i)
a[i]=read();
for(register int i=1;i<=m;++i)
{
int l=read(),r=read();
q[i]=(query){l,r,i,(l-1)/blocksize+1};
}
sort(q+1,q+1+m,cmp);
for(register int i=1;i<=n;++i)
{
pres[i]=pres[i-1]+ys[a[i]]+bs[a[i]]+calc(a[i]);
update(a[i]);
}
clear();
for(register int i=n;i>=1;--i)
{
sufs[i]=sufs[i+1]+ys[a[i]]+bs[a[i]]+calc(a[i]);
update(a[i]);
}
clear();
q[0].l=1,q[0].r=0;
for(register int i=1;i<=m;++i)
{
int pl=q[i-1].l,pr=q[i-1].r,nl=q[i].l,nr=q[i].r;
ans[i]=pres[nr]-pres[pr]+sufs[nl]-sufs[pl];
if(nr>pr)
R[pl-1].push_back((node){pr+1,nr,i,-1});
if(nr<pr)
R[pl-1].push_back((node){nr+1,pr,i,1});
if(nl<pl)
L[nr+1].push_back((node){nl,pl-1,i,-1});
if(nl>pl)
L[nr+1].push_back((node){pl,nl-1,i,1});
}
for(register int i=1;i<=n;++i)
{
update(a[i]);
for(register int j=0;j<R[i].size();++j)
{
int l=R[i][j].l,r=R[i][j].r;
ll tmp=0;
for(register int k=l;k<=r;++k)
tmp+=ys[a[k]]+bs[a[k]]+calc(a[k]);
ans[R[i][j].id]+=tmp*R[i][j].op;
}
}
clear();
for(register int i=n;i>=1;--i)
{
update(a[i]);
for(register int j=0;j<L[i].size();++j)
{
int l=L[i][j].l,r=L[i][j].r;
ll tmp=0;
for(register int k=l;k<=r;++k)
tmp+=ys[a[k]]+bs[a[k]]+calc(a[k]);
ans[L[i][j].id]+=tmp*L[i][j].op;
}
}
for(register int i=1;i<=m;++i)
ans[i]+=ans[i-1],res[q[i].id]=ans[i]+q[i].r-q[i].l+1;
for(register int i=1;i<=m;++i)
write(res[i]),puts("");
return 0;
}

【题解】Luogu P5398 [Ynoi2018]GOSICK的更多相关文章

  1. 洛谷P5398 [Ynoi2018]GOSICK(二次离线莫队)

    题面 传送门 题解 维包一生推 首先请确保您会二次离线莫队 那么我们现在的问题就是怎么转移了,对于\(i\)和前缀\([1,r]\)的贡献,我们拆成\(b_i\)和\(c_i\)两部分,其中\(b_i ...

  2. [题解] Luogu P5446 [THUPC2018]绿绿和串串

    [题解] Luogu P5446 [THUPC2018]绿绿和串串 ·题目大意 定义一个翻转操作\(f(S_n)\),表示对于一个字符串\(S_n\), 有\(f(S)= \{S_1,S_2,..., ...

  3. 题解 Luogu P2499: [SDOI2012]象棋

    关于这道题, 我们可以发现移动顺序不会改变答案, 具体来说, 我们有以下引理成立: 对于一个移动过程中的任意一个移动, 若其到达的位置上有一个棋子, 则该方案要么不能将所有棋子移动到最终位置, 要么可 ...

  4. 题解 luogu P1144 【最短路计数】

    本蒟蒻也来发一次题解第一篇请见谅 这个题有几个要点 1.无向无权图,建图的时候别忘记建来回的有向边[因此WA掉1次 2.无权嘛,那么边长建成1就好了2333333 3.最短路采用迪杰斯特拉(别忘用堆优 ...

  5. 题解 Luogu P1110 【[ZJOI2007]报表统计】

    感谢 @cmy962085349 提供的hack数据,已经改对了. 先声明,我好像是题解里写双$fhq$ $treap$里唯一能过的...(最后两个点啊) 思路:首先看题目,$MIN_GAP_SORT ...

  6. 题解 Luogu P3370

    讲讲这题的几种做法: 暴力匹配法 rt,暴力匹配,即把字符串存起来一位一位判相等 时间复杂度$ O(n^2·m) $ 再看看数据范围 \(n\le10^5,m\le10^3\) 当场爆炸.当然有暴力分 ...

  7. 题解 Luogu P3623 [APIO2008]免费道路

    [APIO2008]免费道路 题目描述 新亚(New Asia)王国有 N 个村庄,由 M 条道路连接.其中一些道路是鹅卵石路,而其它道路是水泥路.保持道路免费运行需要一大笔费用,并且看上去 王国不可 ...

  8. [题解]luogu P4116 Qtree3

    终于来到了Qtree3, 其实这是Qtree系列中最简单的一道题,并不需要线段树, 只要树链剖分的一点思想就吼了. 对于树链剖分剖出来的每一根重链,在重链上维护一个Set就好了, 每一个Set里存的都 ...

  9. 【洛谷5398】[Ynoi2018]GOSICK(二次离线莫队)

    题目: 洛谷 5398 当我刚学莫队的时候,他们告诉我莫队能解决几乎所有区间问题: 现在,当我发现一个区间问题似乎难以用我所了解的莫队解决的时候,他们就把这题的正解叫做 XXX 莫队.--题记 (以上 ...

随机推荐

  1. libreoj #10153 树形dp

    $des$ 有一棵二叉苹果树,如果数字有分叉,一定是分两叉,即没有只有一个儿子的节点.这棵树共 NNN 个节点,标号 1 至 N,树根编号一定为 1. 我们用一根树枝两端连接的节点编号描述一根树枝的位 ...

  2. 前端微信小程序生鲜类仿爱鲜蜂微信小程序

    需求描述及交互分析设计思路和相关知识点首页界面布局设计闪送超市纵向导航设计商品添加到购物车设计购物车商品显示设计收货地址列表显示设计新增收货地址设计 交互分析(1)底部标签导航有首页.闪送超市.购物车 ...

  3. Postgresql 数据库迁移步骤

    1.操作位置:迁移数据库源(旧数据库主机) 找到PostgreSql 的data目录   关闭数据库进程 打包 tar -zcvf pgdatabak.tar.gz data/ ----------- ...

  4. 初识 Python 作业及默写

    1.简述变量量命名规范 2.name = input(“>>>”) name变量是什么数据类型? 3.if条件语句的基本结构? 4.用print打印出下面内容: 文能提笔安天下, 武 ...

  5. Spring Cloud Gateway(十一):全局过滤器GlobalFilter

    本文基于 spring cloud gateway 2.0.1 1.简介 GlobalGilter 全局过滤器接口与 GatewayFilter 网关过滤器接口具有相同的方法定义.全局过滤器是一系列特 ...

  6. TypeScript规则整理

    介绍我在初学 TS 开发项目中遇到的一些问题,希望对你有所帮助~   因为我们的JavaScript是弱类型语言,如果项目过大,或者团队人数很多,不仅代码风格不统一,以后还会很难维护       Ty ...

  7. 剑指offer:二叉搜索树与双向链表

    题目描述: 输入一棵二叉搜索树,将该二叉搜索树转换成一个排序的双向链表.要求不能创建任何新的结点,只能调整树中结点指针的指向. 思路分析: 这道题一开始的思路是借用队列结构,首先中序遍历二叉树,按顺序 ...

  8. java捕获一个网站页面的全部图片

    直接上代码: package com.jeecg.util; import java.io.BufferedReader; import java.io.FileNotFoundException; ...

  9. VS Code中配置python版本以及Python多版本

    VS Code中配置python版本VS Code十分方便配置python的版本:可以选在在本地setting.json或者全局setting.json文件中配置:python.pythonPath在 ...

  10. Axure中继器设置单选

    我们给元件添加组的名称是为了让软件知道哪些元件被放进了一个组中,然后软件会自动让这个组中只有一个元件能够是选中状态,以达到唯一被选中的效果.而中继器的这两个属性默认是启用的状态, 会把组的效果给取消, ...