题目

给出一个长度为n的序列a[]

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

分析

我们可以维护一个前缀和sum,遇到x时加1,遇到y减1。

那么对于区间[l,r],如果sum[r]-sum[l-1]=0,则这个区间合法。

我们可以用桶来求出\(<x,y>\)的合法区间个数。

于是我们\(O(N^3)\)预处理每一个\(<x,y>\);

但是这显然会超时。

因为只有有x和y时位置才是有用的,

我们可以记录x和y所在的位置,这样就可以讲其中很多没用的位置压缩掉。

这样就是\(O(N^2)\)的时间复杂度

#include <cmath>
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>
#include <queue>
#include <map>
const int maxlongint=2147483647;
const int mo=1e9+7;
const int N=8005;
using namespace std;
map <int,int> g;
int tot,a[N],tub[N*2],n,m,d[N],ans[N][N],num,q[N][N/7],re[N];
int prt[20];
void read(int &n)
{
char ch=' ';int q=0,w=1;
for(;(ch!='-')&&((ch<'0')||(ch>'9'));ch=getchar());
if(ch=='-')w=-1,ch=getchar();
for(;ch>='0' && ch<='9';ch=getchar())q=(q<<1)+(q<<3)+ch-'0';n=q*w;
}
void write(int x)
{
if(x<0) putchar('-'),x=-x;
for(;x;x/=10) prt[++prt[0]]=x%10;
if(!prt[0]) prt[++prt[0]]=0;
for (;prt[0];putchar('0'+prt[prt[0]--]));
}
void pre()
{
ans[0][0]=n*(n+1)/2;
for(int i=1;i<=tot;i++)
{
int num=0;
for(int j=1;j<=n;j++)
if(a[j]==i) d[++num]=j;
d[num+1]=n+1;
for(int j=0,dt;j<=num;j++) dt=d[j+1]-d[j]-1,ans[i][0]+=dt*(dt+1)/2;
ans[0][i]=ans[i][0];
}
for(int i=1;i<=tot;i++)
{
ans[i][i]=n*(n+1)/2;
for(int j=i+1,sum;j<=tot;j++)
{
if(i==1 && j==19)
{
printf("");
}
sum=0;
int p=0,p1=0,mx;
if(q[i][p+1]>q[j][p1+1]) mx=q[j][++p1],sum--;
else mx=q[i][++p],sum++;
tub[n]=mx,ans[i][j]+=mx*(mx-1)/2;
while(p<q[i][0] || p1<q[j][0])
{
if(q[i][p+1]>q[j][p1+1])
{
p1++;
ans[i][j]+=(q[j][p1]-mx-1)*(q[j][p1]-mx)/2+(q[j][p1]-mx)*tub[n+sum];
tub[n+sum]+=q[j][p1]-mx;
sum--;
mx=q[j][p1];
}
else
{
p++;
ans[i][j]+=(q[i][p]-mx-1)*(q[i][p]-mx)/2+(q[i][p]-mx)*tub[n+sum];
tub[n+sum]+=q[i][p]-mx;
sum++;
mx=q[i][p];
}
}
ans[i][j]+=(n-mx+1)*tub[sum+n]+(n-mx+1)*(n-mx)/2;
ans[j][i]=ans[i][j];
p=0,p1=0,mx=0;
for(int k=-q[j][0];k<=q[i][0];k++) tub[k+n]=0;
}
}
}
int main()
{
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++)
{
scanf("%d",&a[i]);
if(!g[a[i]]) g[a[i]]=++tot;
re[g[a[i]]]=a[i];
a[i]=g[a[i]];
q[a[i]][++q[a[i]][0]]=i;
}
for(int i=1;i<=tot;i++) q[i][q[i][0]+1]=n+1;
pre();
for(int x,y;m--;)
{
read(x),read(y);
x=g[x],y=g[y];
if(ans[x][y]==14576)
{
printf("");
}
printf("%d\n",ans[x][y]);
}
}

【JZOJ5428】【NOIP2017提高A组集训10.27】查询的更多相关文章

  1. 【JZOJ5430】【NOIP2017提高A组集训10.27】图

    题目 有一个n个点的无向图,给出m条边,每条边的信息形如\(<x,y,c,r>\) 给出q组询问形如\(<u,v,l,r>\) 接下来解释询问以及边的意义 询问表示,一开始你在 ...

  2. 5433. 【NOIP2017提高A组集训10.28】图

    题目描述 Description 有一个n个点A+B条边的无向连通图,有一变量x,每条边的权值都是一个关于x的简单多项式,其中有A条边的权值是k+x,另外B条边的权值是k-x,如果只保留权值形如k+x ...

  3. 【JZOJ5439】【NOIP2017提高A组集训10.31】Calculate

    题目 分析 对于\[\sum_{i=1}^{n}\lfloor\dfrac{T-B_i}{A_i}\rfloor\] 我们考虑拆开处理,得到 \[\sum_{i=1}^{n}(\lfloor\dfra ...

  4. 5432. 【NOIP2017提高A组集训10.28】三元组

    题目 题目大意 给你\(X+Y+Z\)个三元组\((x_i,y_i,z_i)\). 然后选\(X\)个\(x_i\),选\(Y\)个\(y_i\),选\(Z\)个\(z_i\). 每个三元组只能选择其 ...

  5. [JZOJ 5437] [NOIP2017提高A组集训10.31] Sequence 解题报告 (KMP)

    题目链接: http://172.16.0.132/senior/#main/show/5437 题目: 题解: 发现满足上述性质并且仅当A序列的子序列的差分序列与B序列的差分序列相同 于是我们把A变 ...

  6. 【JZOJ5434】【NOIP2017提高A组集训10.30】Matrix

    题目 分析 假设答案为ans, 发现\[k=\sum_{i=1}^{min(n,k)}\lfloor \dfrac{ans}{i} \rfloor\] 于是可以对ans进行二分, 用分块来求出上面的式 ...

  7. 【NOIP2017提高A组集训10.21】Fantasy

    题目 Y sera 陷入了沉睡,幻境中它梦到一个长度为N 的序列{Ai}. 对于这个序列的每一个子串,定义其幻境值为这个子串的和,现在Y sera 希望选择K 个不同的子串并使得这K 个子串的幻境值之 ...

  8. NOIP2017提高A组模拟10.6】Biology

    题目 trie 暴力就是对于每个询问的T个字符串 第i个和第i+1个直接个从后暴力枚举每位是否相同, 但这个方法TLE 我们考虑是否可以用更快的方法来求出两个字符串的最长公共后缀. 我们把所有的字符串 ...

  9. 【NOIP2017提高A组模拟10.7】Adore

    题目 小w 偶然间见到了一个DAG. 这个DAG 有m 层,第一层只有一个源点,最后一层只有一个汇点,剩下的每一层都有k 个节点. 现在小w 每次可以取反第i(1 < i < n - 1) ...

随机推荐

  1. python基础之编码

    ascci:字母.数字.特色字符,1个字节-8位Unicode:两个字节-16位,升级版四个字节-32位uft-8:最少一个字节-8位,英文字母-1个字节-8位,欧洲-2个字节-16位,中文-3个字节 ...

  2. 【VS开发】【Linux开发】【DSP开发】如何截获以太网帧并解析

    1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 3 ...

  3. VS2017:"64位调试操作花费的时间比预期要长",无法运行调试解决办法

    关于这个问题网上搜了好久,参考http://www.yishimei123.com/network/685.html这篇文章,最后终于解决了,在此表示非常感谢! 我的环境是:win10+VS2017 ...

  4. 继续做一道linux的企业 面试题

    把/dongdaxia目录及其子目录小所有以拓展名.sh结尾的文件中包含dongdaxia的字符串全部替换为dj. 解答:这道题还是用到了三剑客里的sed: 第一步:先在/dongdaxia目录及其子 ...

  5. PostgreSQL查询数据库中包含某种类型的表有哪些

    and c.relnamespace = n.oid and nspname = 'public' and a.atttypid = t.oid and typname = 'TEXT' and c. ...

  6. [Luogu5686] 和积和

    Description 给定两个下标从\(1\)到\(n\)编号的序列 \(a_i,b_i\),定义函数\(S(l,r)(1\le l\le r\le n)\)为: \[\sum_{i=l}^r a_ ...

  7. python中进程的几种创建方式

    在新创建的子进程中,会把父进程的所有信息复制一份,它们之间的数据互不影响. 使用os.fork()创建 该方式只能用于Unix/Linux操作系统中,在windows不能用. import os # ...

  8. spark教程(九)-操作数据库

    数据库也是 spark 数据源创建 df 的一种方式,因为比较重要,所以单独算一节. 本文以 postgres 为例 安装 JDBC 首先需要 安装 postgres 的客户端驱动,即 JDBC 驱动 ...

  9. Java加密数据库

    一.背景 数据库配置以明文方式展示如图,会造成安全隐患,如果有黑客入侵会造成密码泄露,信息窃取和破坏等. 二.加密步骤 1.对数据库信息加密: 对数据库中的账号和密码信息进行加密(选择一种算法)然后替 ...

  10. js里生成guid

    function guid() { return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) { | , ...