JZOJ 5428 查询

查询

Description

给出一个长度为n的序列a给出q组询问,每组询问形如(x,y),求a序列的所有区间中,数字x的出现次数与数字y的出现次数相同的区间有多少个。

Data Constraint

1<=n<=8103,1<=q<=51051<=x,y,ai<=109

Solution

先对所有的数离散化。
先处理掉特殊情况:x,y中至少一者未出现在序列a中。
然后考虑怎么预处理询问(x,y)(x,y两者都在序列中出现过),一个显然正确的暴力是维护一个前缀值,扫一遍,如果遇到x就加一,遇到y就减一,然后看前面有多少个前缀值跟当前的值相同,将个数加入答案中。

但这样做的缺点在于每次都要重新O(n)地扫一遍,所以我们可以把x的所有出现位置和y的所有出现位置拿出来,排序之后从前往后扫,两个相邻点之间的前缀值都一样,利用这个性质,可以O(1)把两个相邻点之间的答案都处理完,易证,这样预处理所有 都在a序列中的(x,y)询问的总复杂度为O(n2)。

Code

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>

#define fo(i,j,l) for(int i=j;i<=l;i++)
#define fd(i,j,l) for(int i=j;i>=l;i--)

using namespace std;
typedef long long ll;
const ll N=8e3+4e2,M=68e4,K=100;

struct note{
    int x,w,k;
}px[N+M*2];

int xw[M][2],n,m,j,k,l,i,o,q,a[N],num[M],b[M],e[M],d[M],r[N];
int ans[N][N],lj[2*N],bh[2*N],dq;

int read()
{
    int o=0; char ch=' ';
    for(;ch<'0'||ch>'9';ch=getchar());
    for(;ch>='0'&&ch<='9';ch=getchar())o=o*10+ch-48;
    return o;
}

void pri(int o)
{
    if(o==0)return;else pri(o/10);
    putchar('0'+o%10);
}

void write(int o)
{
    if(o==0)putchar('0');
    else pri(o);
    putchar('\n');
}

bool ksm(note a,note b)
{return a.x<b.x;}
bool ksm2(note a,note b)
{return a.x!=b.x ? a.x<b.x : a.w<b.w ;}

int count(int x,int y)
{
    int an=0;dq++;
    int k1=b[x],k2=b[y],e1=e[x],e2=e[y];
    int f=0,g=0,last=0,now,len=e1+e2-k1-k2+2;
    fo(i,1,len){
        if((px[k1].w<px[k2].w&&k1<=e1)||k2>e2){
            now=px[k1++].w;
            if(now>last)an+=(now-last)*(now-last-1)/2;
            if(bh[f-g+n]!=dq)bh[f-g+n]=dq,lj[f-g+n]=0;
            if(now>last)an+=(now-last)*lj[f-g+n];
            lj[f-g+n]+=now-last;
            f++;
            last=now;
        }else{
            now=px[k2++].w;
            if(now>last)an+=(now-last)*(now-last-1)/2;
            if(bh[f-g+n]!=dq)bh[f-g+n]=dq,lj[f-g+n]=0;
            if(now>last)an+=(now-last)*lj[f-g+n];
            lj[f-g+n]+=now-last;
            g++;    
            last=now;
        }
    }
    if(last<=n)an+=(n-last)*(n-last+1)/2;
    if(bh[f-g+n]!=dq)bh[f-g+n]=dq,lj[f-g+n]=0;
    if(last<=n)an+=(n-last+1)*lj[f-g+n];
    return an;
}

int tj(int o)
{
    int last=0,kk=0;
    fo(i,b[o],e[o]){    
        if(last+1<px[i].w)kk+=(px[i].w-last)*(px[i].w-last-1)/2;
        last=px[i].w;
    }
    if(last<n)kk+=(n-last)*(n-last+1)/2;
    return kk;
}

int main()
{
    n=read(); q=read();
    fo(i,1,n)px[i].x=read(),px[i].w=0,px[i].k=i;
    fo(i,1,q){
        px[i*2+n-1].x=read(),px[i*2+n-1].w=1,px[i*2+n-1].k=i*2-1;
        px[i*2+n].x=read(),px[i*2+n].w=1,px[i*2+n].k=i*2;
    }
    sort(px+1,px+(n+2*q)+1,ksm);
    px[0].x=0; int kk=0;
    fo(i,1,n+2*q){
        kk+=(px[i].x!=px[i-1].x);
        if(!px[i].w)a[px[i].k]=kk;
        else xw[(px[i].k+1)/2][!(px[i].k%2>0)]=kk;
    }
    fo(i,1,n)px[i].x=a[i],px[i].w=i;
    sort(px+1,px+n+1,ksm2);
    int v=0;
    fo(i,1,n){
        if(px[i].x!=px[i-1].x)d[px[i].x]=++v,b[v]=i;
        num[a[i]]++;
        e[v]=i;
    }
    fo(i,1,v-1)fo(l,i+1,v)ans[i][l]=ans[l][i]=count(i,l);
    fo(i,1,v)r[i]=tj(i),ans[i][i]=n*(n+1)/2;
    int gd=n*(n+1)/2;
    fo(i,1,q){
        int u=xw[i][0],v=xw[i][1];
        if((num[u]|num[v])==0)write(gd);
        else if(num[u]==0)write(r[d[v]]);
        else if(num[v]==0)write(r[d[u]]);
        else write(ans[d[v]][d[u]]);
    }
}
已经博主授权,源码转载自 https://pan.quark.cn/s/e577710b7191 ### 解决Win10系统中Word文件图标显示不正常问题 #### 问题描述 在Windows 10操作系统中,部分用户遇到Word文档图标呈现非正常状态的问题。具体表现为:本应展示为Microsoft Word图标的DOC或DOCX文件,在系统中却呈现为常规的文本文件图标。这种现象不仅降低了用户的视觉体验,还可能引发一定的操作不便。 #### 解决方案 ##### 方法一:借助注册表编辑来纠正图标显示异常 1. **进行注册表备份**:为了保障系统的稳定性,在开展任何注册表修改之前,必须对注册表进行备份。可以通过“导出”功能来达成备份目的。 - 启动“运行”对话框(快捷键:`Windows + R`),键入`regedit`,随后按回车键进入注册表编辑界面。 - 在注册表编辑界面中,找到菜单栏里的“文件”选项,点击后选择“导出”,依照提示完成注册表备份。 2. **移除相关注册表项**: - 在`HKEY_CLASSES_ROOT`下,删除以下四个注册表项: - `.doc` - `.docx` - `Word.Document.8` - `Word.Document.12` - 在`HKEY_LOCAL_MACHINE\SOFTWARE\Classes`下,同样移除上述四个注册表项。 3. **重新启动计算机**:执行完上述步骤后,重新启动计算机以使修改生效。 #### 方法二:通过调整文件关联来纠正图标显示异常 如果第一种方法未能解决难题,则可以尝试调整文件的关联方式,具体步骤如下: 1. **移除文件关联**: - 在`HKEY_CLASSES_ROOT`下删除`....
源码直接下载地址: https://pan.quark.cn/s/a4b39357ea24 台达VFD037E43A变频器使用说明书包含了产品的基础安装、操作及维护等方面的全面信息,以下为其知识要点具体阐述: 1. 安全操作注意事项:在操作台达VFD037E43A变频器之前,说明书着重指出必须研读安全信息以保障操作人员与设备的双重安全。使用前应核实电源已切断,防止触碰带电线路,同时对内部电路板的静电防护措施也做了规定。此外,说明书还明确禁止非专业人员擅自改装变频器。 2. 接地规范:说明书说明了230V和460V系列变频器分别遵循第三类接地和特殊接地标准,从而确保了安全接地的合规性。 3. 安装与连接:说明书详尽说明了产品装置、搬运、接线方法、主回路端子及控制回路端子等环节,为用户正确配置和连接变频器提供了指导。 4. 零件选择:说明书内含零件选购参考,协助用户依据实际需求挑选适配的零件。 5. 参数调节:说明书中的“参数索引”及“参数深入解释”部分指导用户如何设定和调整变频器的运行参数。 6. 应用案例:在“成功实施案例”部分,说明书以实例形式向用户展示变频器在不同工作场景下的应用技巧。 7. 问题诊断:说明书提供了“警示代码解析”和“错误代码解析”,帮助用户识别变频器的常见故障并进行排除。 8. 通讯方式:说明书介绍了“CANopen通讯基础”和“BACnet应用指南及流程”,使用户能够掌握如何通过这些通讯方式将变频器融入工业自动化系统。 9. 特殊功能介绍:说明书还收录了“可编程逻辑控制器应用”和“PT100操作指南”,阐述了变频器的可编程逻辑控制器特性及温度传感器操作方法。 10. 网站与升级:说明书指出产品资料如有变动可通过台达电子工业自动化类产品的官方网...
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值