首页 > 其他分享 >P9212 「蓬莱人形」

P9212 「蓬莱人形」

时间:2023-10-18 15:11:28浏览次数:34  
标签:le res int P9212 sqrt 人形 蓬莱 return mod

题外话

  • 是图老师推的题捏。

  • 第 70 道紫,纪念一下。

  • 写这题写了好久啊,都要调崩溃了,终于过了/ll

  • 之前一直没尝试过写值域分块,今天第一次写竟然没出锅。


\(\text{Links}\)

原题传送门


题意

给定一个长度为 \(n\) \((n\le 10^5)\) 的序列 \(a\) \((1\le a_i\le 10^5)\),你需要回答 \(q\) \((q\le 5\times 10^5)\) 次询问(非强制在线),每次询问给出参数 \(l,r,x,y,m\) \((1\le l\le r\le n,1\le x,y,m\le 10^5)\),求有多少个 \(i\in[l,r]\) 满足 \((a_i+x)\mod m\lt (a_i+y)\mod m\)。

题解

先考虑转化一下那个不等式,这一步应该不是很难,我的方法是,肯定先把 \(x,y\) 都对 \(m\) 取模,然后钦定 \(x\lt y\),然后分别以 \(x\) 和 \(y\) 为断点画出两条以 \(\mod m\) 的余数环断开形成的链。此时容易发现,记 \(a'_i=a_i\mod m\),则有当 $a'_i\in [0,m-y)\cup [m-x,m) $ 时,\(i\) 满足条件。\(x\gt y\) 的情况交换 \(x\) 和 \(y\),然后用区间长度减去算出的结果就是答案;\(x=y\) 的情况显然无解。

于是问题转化为每次给定一个下标范围 \([l,r]\) 和一个值域范围 \([x,y]\) 以及 \(m\),求 \([l,r]\) 中有多少数对 \(m\) 取模后的值在范围 \([x,y]\) 中。

这个计数问题的答案显然具有可差分性,所以我们每次在 \(r\) 的地方存下这个询问,并给它赋一个正号(\(+\)),再在 \(l-1\) 的地方存下这个询问,并给它赋一个负号(\(-\)),然后我们只需要用这种方式把询问离线下来从 \(1\) 到 \(n\) 扫一遍,中途遇到挂了询问的地方就计算 \([1,i]\) 的答案,然后根据 \(+/-\) 把贡献丢给对应的询问就行了。

然后考虑怎么维护这个计数。其实挺简单。

取模。直接上根号分治。设值域上限为 \(V\)。

当 \(m\le \sqrt V\) 时,我们直接开个桶 \(cnt_{i,j}\) 表示 \(\mod i\) 结果为 \(j\) 的数有多少个,每次 \(O(\sqrt V)\) 插入,\(O(\sqrt V)\) 查询即可,则此部分复杂度为 \(O(n\sqrt V+q\sqrt V)\)。

当 \(m\gt \sqrt V\) 时,我们每次把目标值域范围暴力地往上跳,每跳一次上下界同时 \(+m\),所以最多跳 \(O(\sqrt V)\) 到顶就可以结束了。于是我们每次要回答有多少个 \(i\) 满足 \(a_i\in [l,r]\),值域分块即可。因为总共有 \(O(q\sqrt V)\) 次查询和 \(O(n)\) 次插入,所以得写一个 \(O(\sqrt V)\) 插入,\(O(1)\) 查询的值域分块来平衡复杂度,每次记录块内前缀和、块内后缀和以及块间前缀和即可。此部分复杂度为 \(O(n\sqrt V+q\sqrt V)\)。

总时间复杂度为 \(O(q\sqrt V+q\sqrt V)\),只要不是实现得太烂的都能过。

\(\text{Code:}\)

#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define il inline
#define re register
const int N=1e5+113,M=5e5+113,SQ=370;
int n,m,a[N],L=1,R,cnt[N],ans[M],c[N];
int s[SQ][SQ];
int T,idv[N],vl[N],vr[N],vmax,pre[N],suf[N],sv[N];
struct query{
    int f,x,y,mod,id;
};
vector<query>v[N];
#define pb push_back
il int read(){
    re int x=0,f=1;char c=getchar();
    while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
    while(c>='0'&&c<='9')x=(x<<3)+(x<<1)+(c^48),c=getchar();
    return x*f;
}
il void init(){
    for(re int i=1;i<=vmax;i++)idv[i]=(i-1)/T+1;
    for(re int i=1;i<=idv[vmax];i++)
        vl[i]=vr[i-1]+1,vr[i]=i*T;
    vr[idv[vmax]]=vmax;
}
il int Ask(int x,int y,int mod){
    if(x>y)return 0;
    int res=0;
    for(re int i=x;i<=y;i++)res+=s[mod][i];
    return res;
}
il int solve_le(int l,int r,int x,int y,int mod){
    if(mod==1)return 0;
    if(x==y)return 0;
    bool flg=0;
    if(x>y)swap(x,y),flg=1;
    int res=Ask(mod-x,mod-1,mod)+Ask(0,mod-y-1,mod);
    return flg?r-l+1-res:res;
}
il int GetCntV(int l,int r){
    if(idv[l]==idv[r])return (l==vl[idv[l]])?pre[r]:pre[r]-pre[l-1];
    return suf[l]+pre[r]+sv[idv[r]-1]-sv[idv[l]];
}
il int solve_gt(int l,int r,int x,int y,int mod){
    if(mod==1)return 0;
    if(x==y)return 0;
    bool flg=0;
    if(x>y)swap(x,y),flg=1;
    int res=0,now=mod;
    if(x){
        int l1=mod-x,r1=mod-1;
        while(1){
            res+=GetCntV(l1,r1);
            if(r1==vmax)break;
            if(l1+mod>vmax)break;
            l1+=mod,r1+=mod;
            r1=min(r1,vmax);
        }
    }
    int l2=0,r2=mod-y-1;
    while(1){
        res+=GetCntV(l2,r2);
        if(r2==vmax)break;
        if(l2+mod>vmax)break;
        l2+=mod,r2+=mod;
        r2=min(r2,vmax);
    }
    return flg?r-l+1-res:res;
}
il void Add(int x){
    for(re int i=1;i<=T;i++)s[i][x%i]++;
    for(re int i=x;i<=vr[idv[x]];i++)pre[i]++;
    for(re int i=vl[idv[x]];i<=x;i++)suf[i]++;
    for(re int i=idv[x];i<=idv[vmax];i++)sv[i]++;
}
int main(){
    n=read(),m=read();
    for(re int i=1;i<=n;i++)a[i]=read(),vmax=max(vmax,a[i]);
    T=sqrt(vmax);
    for(re int i=1;i<=m;i++){
        int l=read(),r=read(),x=read(),y=read(),mod=read();
        x%=mod,y%=mod;
        if(l>1)v[l-1].pb({-1,x,y,mod,i});
        v[r].pb({1,x,y,mod,i});
    }
    init();
    for(re int i=1;i<=n;i++){
        Add(a[i]);
        for(re query j:v[i]){
            if(j.mod>T)ans[j.id]+=j.f*solve_gt(1,i,j.x,j.y,j.mod);
            else ans[j.id]+=j.f*solve_le(1,i,j.x,j.y,j.mod);
        }
    }
    for(re int i=1;i<=m;i++)cout<<ans[i]<<'\n';
    return 0;
}

标签:le,res,int,P9212,sqrt,人形,蓬莱,return,mod
From: https://www.cnblogs.com/MrcFrst-LRY/p/17772400.html

相关文章

  • 【根号分治】P9212 「蓬莱人形」 题解
    P9212看到除法相关容易想到根号分治。先对\(x,y\)进行讨论,不妨令\(0\lex,y<m\)。\(x<y\)时,当满足\(a_i+y<m\)或\(a_i+x\gem\)时,即当\(a_i<m-y\)或\(a_i\gem-x\)满足\((a_i+x)\bmodm<(a_i+y)\bmodm\),即\(a_i\bmodm\in[0,m-y-1]\bigcup[m-x,m......
  • 视频融合/监控汇聚平台EasyCVR人形检测算法应用汇总
    安防视频监控平台EasyCVR是一个具有强大拓展性、灵活的视频能力和轻便部署的平台。它支持多种主流标准协议,包括国标GB28181、RTSP/Onvif、RTMP等,还可以支持厂家的私有协议和SDK接入,例如海康Ehome、海大宇等设备的SDK。该平台不仅拥有传统安防视频监控的功能,还具备接入AI智能分析的......
  • GPT 被曝重大缺陷;腾讯侦破国内首个 AI 游戏外挂;特斯拉人形机器人再进化丨 RTE 开发者
    开发者朋友们大家好:这里是「RTE开发者日报」,每天和大家一起看新闻、聊八卦。我们的社区编辑团队会整理分享RTE(RealTimeEngagement)领域内「有话题的新闻」、「有态度的观点」、「有意思的数据」、「有思考的文章」、「有看点的会议」,但内容仅代表编辑的个人观点,欢迎大家留......
  • 安防监控/视频云存储/视频AI智能分析:人形检测算法应用汇总
    随着人工智能的飞速发展,TSINGSEE青犀智能AI算法功能也日渐丰富,除了常见的人脸、工服、安全帽检测以外,人形检测算法的应用也十分广泛,主要可以应用在以下场景:1、安防监控系统人形检测算法可以应用于监控摄像头中,实时检测和跟踪人体目标。当有可疑人员进入监控区域时,系统可以自动发出......
  • 安防监控系统/视频云存储/视频AI智能分析:人形检测算法应用汇总
    随着人工智能的飞速发展,TSINGSEE青犀智能AI算法功能也日渐丰富,除了常见的人脸、工服、安全帽检测以外,人形检测算法的应用也十分广泛,主要可以应用在以下场景:1、安防监控系统人形检测算法可以应用于监控摄像头中,实时检测和跟踪人体目标。当有可疑人员进入监控区域时,系统可以自动......
  • 一大波特斯拉人形机器人上线,马斯克震撼官宣2款新车!
    【导读】这次特斯拉股东日,虽没有新车,但马斯克确定Cybertruck今年一定会来。特斯拉股东日,依旧没有新车。万众瞩目的马斯克登台继续画饼,「我不官宣新车,不过新车年销量会超过500万」。马斯克向所有人展示了特斯拉正在研发的2款新车,新车的样子在屏幕中一闪而过。具体配置,只字未提。从比......
  • 川田工业开发出可和人类协作的人形机器人
    日本的川田工业株式会社开发出一个人形机器人,专门设计来用于和人类一起工作。这个叫Nextage的并不是此类机器人中的第一个,但其特别之处给人印象很深刻,而且已经商业化运作。其配备一个高速立体摄像头和两只手臂,每只有12个关节,可精确定位到30微米之内。当人类靠近,为了安全,其......
  • 抗衡特斯拉擎天柱,人形机器人第一股实至名归?
    文|智能相对论作者|佘凯文前有ChatGPT带动之下大热的AIGC,后有仍在大银幕热映的《流浪地球2》,要问今年开年,哪个赛道最火?非机器人莫属。机器人行业有着“制造业皇冠顶端的......
  • 抗衡特斯拉擎天柱,人形机器人第一股实至名归?
    文|智能相对论作者|佘凯文前有ChatGPT带动之下大热的AIGC,后有仍在大银幕热映的《流浪地球2》,要问今年开年,哪个赛道最火?非机器人莫属。机器人行业有着“制造业皇冠顶端的......
  • Gee引擎架设教程:Gee引擎人形怪物设置,MonUseItems配置文件讲解
    人形怪物设置说明:1、在Envir目录下增加MonUseItems目录,放置怪的配置文件,见MonUseItems目录2、Monster.DB范例:战士;150;19;0;198;0;100;5000;0;10;10;0;0;0;0;88;45;450;1;0;......