题目大意:
  给你一个长度为$n(n\leq 5\times 10^5)$的序列$A_{1\sim n}$。求满足区间众数在区间内出现次数严格大于$\lfloor\frac{r-l+1}{2}\rfloor$的区间$[l,r]$的个数。

思路:
  分治。
  对于一个区间$[l,r]$,设$mid=\lfloor\frac{l+r}{2}\rfloor$,我们可以求出所有经过$mid$的区间内能够成为众数的所有数。
  不难发现所有的区间众数满足如下一个性质:如果$x$是区间$[l,r]$的众数,那么对于$l\leq x\leq r$,$x$一定是区间$[l,k]$或区间$(k,r]$的众数。
  利用这一性质,我们可以令$k=mid$,这样就可以$O(n)$从$mid$出发往左右两边扫,求出能够成为众数的所有数。
  接下来枚举每个众数$x$,求一下当前$[l,r]$区间中,以$x$作为众数的子区间个数。
  具体我们可以先从$mid$往左扫,设往左扫到的端点为$b$,记录一下对于不同的$b$,$mid-b+1-cnt[x]$不同取值的出现次数。然后再往右扫,求出对于当前右端点$e$,求出满足$e-b+1-cnt[x]>\lfloor\frac{e-b+1}{2}\rfloor$的区间$[b,e]$的个数,这可以用前缀和快速求出。
  这样我们就统计了区间$[l,r]$,经过$mid$的所有子区间。
  对于不经过$mid$的子区间可以递归求解。
  递归树中,每一层区间长度加起来是$n$,可能的众数个数有$\log n$个,每一层的时间复杂度是$O(n\log n)$。总共有$\log n$层,总的时间复杂度是$O(n\log^2 n)$。

 #include<cstdio>
#include<cctype>
#include<algorithm>
typedef long long int64;
inline int getint() {
register char ch;
while(!isdigit(ch=getchar()));
register int x=ch^'';
while(isdigit(ch=getchar())) x=(((x<<)+x)<<)+(ch^'');
return x;
}
const int N=;
int a[N],pos[N],num[N],cnt[N*];
int64 ans;
void solve(const int &l,const int &r) {
if(l==r) {
ans++;
return;
}
const int mid=(l+r)/;
solve(l,mid);
solve(mid+,r);
for(register int i=mid;i>=l;i--) {
if(++cnt[a[i]]>(mid-i+)/) {
if(!pos[a[i]]) {
num[pos[a[i]]=++num[]]=a[i];
}
}
}
for(register int i=mid+;i<=r;i++) {
if(++cnt[a[i]]>(i-mid)/) {
if(!pos[a[i]]) {
num[pos[a[i]]=++num[]]=a[i];
}
}
}
for(register int i=l;i<=r;i++) {
pos[a[i]]=cnt[a[i]]=;
}
for(register int i=;i<=num[];i++) {
int sum=r-l+,max=sum,min=sum;
cnt[sum]=;
for(register int j=l;j<mid;j++) {
if(a[j]==num[i]) {
sum++;
} else {
sum--;
}
max=std::max(max,sum);
min=std::min(min,sum);
cnt[sum]++;
}
if(a[mid]==num[i]) {
sum++;
} else {
sum--;
}
for(register int i=min;i<=max;i++) {
cnt[i]+=cnt[i-];
}
for(register int j=mid+;j<=r;j++) {
if(a[j]==num[i]) {
sum++;
} else {
sum--;
}
ans+=cnt[std::min(max,sum-)];
}
for(register int i=min;i<=max;i++) {
cnt[i]=;
}
}
num[]=;
}
int main() {
const int n=getint(); getint();
for(register int i=;i<=n;i++) {
a[i]=getint();
}
solve(,n);
printf("%lld\n",ans);
return ;
}

[BZOJ5110]Yazid的新生舞会的更多相关文章

  1. 【BZOJ5110】[CodePlus2017]Yazid 的新生舞会 线段树

    [BZOJ5110][CodePlus2017]Yazid 的新生舞会 Description Yazid有一个长度为n的序列A,下标从1至n.显然地,这个序列共有n(n+1)/2个子区间.对于任意一 ...

  2. bzoj5110: [CodePlus2017]Yazid 的新生舞会

    Description Yazid有一个长度为n的序列A,下标从1至n.显然地,这个序列共有n(n+1)/2个子区间.对于任意一个子区间[l,r] ,如果该子区间内的众数在该子区间的出现次数严格大于( ...

  3. 【bzoj5110】Yazid的新生舞会

    这里是 $THUWC$ 选拔时间 模拟赛的时候犯 $SB$ 了,写了所有的部分分,然后直接跑过了 $4$ 个大样例(一个大样例是一个特殊情况)…… 我还以为我非常叼,部分分都写对了,于是就不管了…… ...

  4. [loj 6253] Yazid的新生舞会

    (很久之前刷的题现在看起来十分陌生a) 题意: 给你一个长度为n的序列A,定义一个区间$[l,r]$是“新生舞会的”当且仅当该区间的众数次数严格大于$\frac{r-l+1}{2}$,求有多少子区间是 ...

  5. 【BZOJ5110】[CodePlus2017]Yazid 的新生舞会

    题解: 没笔的时候我想了一下 发现如果不是出现一半次数而是k次,并不太会做 然后我用前缀和写了一下发现就是维护一个不等式: 于是就可以随便维护了

  6. 【bzoj5110】[CodePlus2017]Yazid 的新生舞会 Treap

    题目描述 求一个序列所有的子区间,满足区间众数的出现次数大于区间长度的一半. 输入 第一行2个用空格隔开的非负整数n,type,表示序列的长度和数据类型.数据类型的作用将在子任务中说明. 第二行n个用 ...

  7. BZOJ5110 CodePlus2017Yazid 的新生舞会(线段树)

    考虑统计每个数字的贡献.设f[i]为前缀i中该数的出现次数,则要统计f[r]-f[l]>(r-l)/2的数对个数,也即2f[r]-r>2f[l]-l. 注意到所有数的f的总变化次数是线性的 ...

  8. BZOJ.5110.[CodePlus2017]Yazid 的新生舞会(线段树/树状数组/分治)

    LOJ BZOJ 洛谷 又来发良心题解啦 \(Description\) 给定一个序列\(A_i\).求有多少个子区间,满足该区间众数出现次数大于区间长度的一半. \(n\leq5\times10^5 ...

  9. 「CodePlus 2017 11 月赛」Yazid 的新生舞会(树状数组/线段树)

    学习了新姿势..(一直看不懂大爷的代码卡了好久T T 首先数字范围那么小可以考虑枚举众数来计算答案,设当前枚举到$x$,$s_i$为前$i$个数中$x$的出现次数,则满足$2*s_r-r > 2 ...

随机推荐

  1. python基础实践(四)

    # -*- coding:utf-8 -*-# Author:sweeping-monkwhy = "为什么要组织列表?"print(why)Chicken_soup = &quo ...

  2. c# asp.net 中使用token验证

    基于token的鉴权机制类似于http协议也是无状态的,它不需要在服务端去保留用户的认证信息或者会话信息.这就意味着基于token认证机制的应用不需要去考虑用户在哪一台服务器登录了,这就为应用的扩展提 ...

  3. 个人支付宝监控并自动获取交易记录对接系统API

    我们都知道,支付宝支付API接口只有企业才能使用,但有一部分业务,可能我们不方便使用企业收款,但又想做到自动化,那怎么办呢 于是一个支付宝交易记录自动监控软件诞生了. 支付宝都有一个收款二维码,收款提 ...

  4. DOM对象转化成jQuery对象

    相比较jQuery转化成DOM,开发中更多的情况是把一个DOM对象加工成jQuery对象.$(参数)是一个多功能的方法,通过传递不同的参数而产生不同的作用. 如果传递给$(DOM)函数的参数是一个DO ...

  5. css控制文字模糊

    *{ color: transparent; text-shadow: #111 0 0 5px; }

  6. poj 2253 Frogger (最短路径)

    Frogger Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 22557   Accepted: 7339 Descript ...

  7. POJ 2891 Strange Way to Express Integers | exGcd解同余方程组

    题面就是让你解同余方程组(模数不互质) 题解: 先考虑一下两个方程 x=r1 mod(m1) x=r2 mod (m2) 去掉mod x=r1+m1y1   ......1 x=r2+m2y2   . ...

  8. Educational Codeforces Round 42 (Rated for Div. 2) B

    B. Students in Railway Carriage time limit per test 2 seconds memory limit per test 256 megabytes in ...

  9. shell脚本——项目1

    案例名称:系统初始化 背景:10台已装有linux系统的服务器 需求: 1.设置时区同步 2.禁用selinux 3.清空防火墙策略 4.历史命令显示操作时间 5.禁止root远程登录 6.禁止定时任 ...

  10. mac使用基础

    Mac 系统的桌面 Mac 的桌面是一个很炫的3D, 背景是一张“星空”图. 2 Dock:  在桌面的下方有一排图标, 叫Dock, 用来快速启动程序, 进入文件夹, 它同时还可以停靠正在运行的程序 ...