题目大意:

一个数列,求有多少个区间$[l,r]$满足该区间的众数出现次数大于$\lceil \frac{r-l}{2} \rceil$

思路:

对于一个区间满足条件的众数明显是唯一的 所以设该数的前缀和数组为$S$

则一个区间$(l,r]$满足条件满足$2 \times (S_r-S_l)>(r-l)$ 移项后得到$2 \times S_r-r>2 \times S_l-l$

则对于$2 \times S_i-i$建立函数发现该函数由斜率为$\pm 1$组成

所有函数的关键点总数为$n$ 对于$y$轴建立权值线段树 发现中间连续的一段的贡献为一次函数

写一波一次函数即可

 #include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<vector>
#include<queue>
#include<map>
#include<set>
#define rep(i,s,t) for(register int i=(s),i__end=(t);i<=i__end;++i)
#define dwn(i,s,t) for(register int i=(s),i__end=(t);i>=i__end;++i)
#define ren(x) for(register int i=fst[x];i;i=nxt[i])
#define pb(a,x) vec[a].push_back(x);
#define ll long long
#define inf 2139062143
#define MAXN 1001000
using namespace std;
inline int read()
{
int x=,f=;char ch=getchar();
while(!isdigit(ch)) {if(ch=='-') f=-;ch=getchar();}
while(isdigit(ch)) {x=x*+ch-'';ch=getchar();}
return x*f;
}
int n,N,tp,g[MAXN],hsh[MAXN],m,tagk[MAXN<<],tagb[MAXN<<];
ll sum[MAXN<<],ans;
vector <int> vec[MAXN];
inline ll calc(ll k,ll b,int x,int y) {return ((ll)((ll)k*y+k*x+*b)*((ll)y-x+))/;}
void pshd(int k,int l,int r,int mid)
{
sum[k<<]+=calc(tagk[k],tagb[k],l,mid);
sum[k<<|]+=calc(tagk[k],tagb[k],mid+,r);
tagk[k<<]+=tagk[k],tagk[k<<|]+=tagk[k],tagb[k<<]+=tagb[k],tagb[k<<|]+=tagb[k];
tagk[k]=tagb[k]=0LL;
}
void mdf(int k,int l,int r,int a,int b,ll d,ll t)
{
if(l==a&&r==b) {tagb[k]+=t,tagk[k]+=d,sum[k]+=calc(d,t,l,r);return ;}
int mid=l+r>>;if(tagb[k]!=||tagk[k]!=) pshd(k,l,r,mid);
if(b<=mid) mdf(k<<,l,mid,a,b,d,t);else if(a>mid) mdf(k<<|,mid+,r,a,b,d,t);
else {mdf(k<<,l,mid,a,mid,d,t);mdf(k<<|,mid+,r,mid+,b,d,t);}
sum[k]=sum[k<<]+sum[k<<|];
}
ll query(int k,int l,int r,int a,int b)
{
if(l==a&&r==b) return sum[k];
int mid=l+r>>;if(tagb[k]!=||tagk[k]!=) pshd(k,l,r,mid);
if(b<=mid) return query(k<<,l,mid,a,b);
else if(a>mid) return query(k<<|,mid+,r,a,b);
else return query(k<<,l,mid,a,mid)+query(k<<|,mid+,r,mid+,b);
}
void work(int x)
{
int t,las=,pos;rep(i,,vec[x].size()-)
{
t=vec[x][i],pos=las-(t-vec[x][i-])+;
ans+=query(,,N,pos+n,las+n);
mdf(,,N,pos+n+,las+n+,,-pos-n);
if(las+n+<=N) mdf(,,N,las+n+,N,,las-pos+);
las=pos+;
}
las=;rep(i,,vec[x].size()-)
{
t=vec[x][i],pos=las-(t-vec[x][i-])+;
mdf(,,N,pos+n+,las+n+,-,pos+n);
if(las+n+<=N) mdf(,,N,las+n+,N,,pos-las-);
las=pos+;
}
}
int main()
{
n=read(),N=(n<<)+,tp=read();rep(i,,n) {g[i]=read();if(!hsh[g[i]]) hsh[g[i]]=++m;}
rep(i,,m) pb(i,);rep(i,,n) pb(hsh[g[i]],i);rep(i,,m) pb(i,n+);
rep(i,,m) work(i);printf("%lld\n",ans);
}

bzoj 5110 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. [loj 6253] Yazid的新生舞会

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

  4. [BZOJ 4819] [SDOI 2017] 新生舞会

    Description 学校组织了一次新生舞会,Cathy作为经验丰富的老学姐,负责为同学们安排舞伴. 有 \(n\) 个男生和 \(n\) 个女生参加舞会买一个男生和一个女生一起跳舞,互为舞伴. C ...

  5. 【bzoj5110】Yazid的新生舞会

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

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

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

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

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

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

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

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

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

随机推荐

  1. 【数据库-Azure SQL Database】如何创建事务复制将本地数据同步到 SQL Azure

    Azure SQL DB 可以被配置成为 SQL Server 事务复制的一个订阅者( subscriber ). 主要应用场景有两种: 将您的数据迁移到 Azure SQL DB, 并且没有宕机时间 ...

  2. Oracle错误(包括PL/SQL)集合与修复

    +-----------------------------------------------------------------------+ |   在本篇随笔中,仅根据个人经验累积错误进行描述 ...

  3. SQLite-表达式

    SQLite -表达式 一个表达式是一个或多个值的组合,运算符和SQL函数,评价一个值. SQL表达式就像公式和都写在查询语言.您还可以使用为特定的数据集查询数据库. 语法: 考虑到SELECT语句的 ...

  4. 迅为iMX6Q/PLUS开发板烧写设备树内核 Qt 系统

    迅为iMX6Q 和 iMX6PLUS 两个硬件版本,设备树镜像的烧写方法以及镜像所在目录,镜像名称全部一致. 如果用的是 iMX6Q 版本,想要烧写设备树版本镜像,请使用 iMX6Q 设备树版本的光盘 ...

  5. poj3264 划分树

    题意: 给定一个序列,询问区间中最大数减去最小数的结果 和2104差不多, 代码贴过来就OK了 #include <iostream> #include <algorithm> ...

  6. 2010: C语言实验——逆置正整数

    2010: C语言实验——逆置正整数 Time Limit: 1 Sec  Memory Limit: 64 MBSubmit: 949  Solved: 691[Submit][Status][We ...

  7. BCB:内存泄漏检查工具CodeGuard

    一.为什么写这篇东西 自己在使用BCB5写一些程序时需要检查很多东西,例如内存泄漏.资源是否有释放等等,在使用了很多工具后,发觉BCB5本身自带的工具―CodeGuard,非常不错,使用也挺方便的,但 ...

  8. Dubbo中的监控和管理

    一.Dubbo中的监控 1.原理 原理:服务消费者和提供者,在内存中累计调用次数和调用时间,定时每分钟发送一次统计数据到监控中心. 2.搭建监控服务 3.修改配置文件 修改注册中心的地址: 注意:这个 ...

  9. bootstrap历练实例: 基本胶囊式的导航菜单

    <!DOCTYPE html><html><head><meta http-equiv="Content-Type" content=&q ...

  10. usb3.0驱动

    usb3.0驱动下载地址 华硕注入usb3.0驱动工具下载地址 https://dlsvr04.asus.com/pub/ASUS/misc/utils/ASUS_EZInstaller_V10306 ...