BZOJ5110 CodePlus2017Yazid 的新生舞会(线段树)
考虑统计每个数字的贡献。设f[i]为前缀i中该数的出现次数,则要统计f[r]-f[l]>(r-l)/2的数对个数,也即2f[r]-r>2f[l]-l。
注意到所有数的f的总变化次数是线性的,考虑对每次变化进行统计。
对于当前考虑位置i,统计r∈[i,nxt[a[i]])时a[i]的贡献。如果将之前的所有2f[l]-l扔进一个线段树里,可以发现要统计的是终点在一段区间内的前缀和的和。那么不属于该区间的每个2f[l]-l都会被统计nxt[a[i]]-i次,属于该区间的2f[l]-l的被统计次数构成一个等差数列,维护区间和的同时再维护区间前缀和的和即可。统计完后把这段作为l的贡献加进去,就是一个线段树区间加。
写的是动态开点,然而在下传标记的时候忘记开新点了,于是浪费了两个小时宝贵的人生。bzoj上T掉了然而没心情卡常了。
#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstdlib>
#include<cstring>
#include<algorithm>
using namespace std;
#define ll long long
#define N 500010
int read()
{
int x=,f=;char c=getchar();
while (c<''||c>'') {if (c=='-') f=-;c=getchar();}
while (c>=''&&c<='') x=(x<<)+(x<<)+(c^),c=getchar();
return x*f;
}
char getc(){char c=getchar();while ((c<'A'||c>'Z')&&(c<'a'||c>'z')) c=getchar();return c;}
int gcd(int n,int m){return m==?n:gcd(m,n%m);}
int n,a[N],nxt[N],p[N],f[N],cnt,root[N];
ll ans=;
struct data{int l,r,sum,lazy;ll pre;
}tree[N*];
void update(int &k,int l,int r,int x)
{
if (!k) k=++cnt;
tree[k].sum+=(r-l+)*x;
tree[k].pre+=1ll*x*(r-l+)*(r-l+)>>;
tree[k].lazy+=x;
}
void down(int k,int l,int r)
{
update(tree[k].l,l,l+r>>,tree[k].lazy),update(tree[k].r,(l+r>>)+,r,tree[k].lazy);
tree[k].lazy=;
}
int querys(int k,int l,int r,int x,int y)
{
if (!k) return ;
if (l==x&&r==y) return tree[k].sum;
if (tree[k].lazy) down(k,l,r);
int mid=l+r>>;
if (y<=mid) return querys(tree[k].l,l,mid,x,y);
else if (x>mid) return querys(tree[k].r,mid+,r,x,y);
else return querys(tree[k].l,l,mid,x,mid)+querys(tree[k].r,mid+,r,mid+,y);
}
ll querypre(int k,int l,int r,int x,int y)
{
if (!k) return ;
if (l==x&&r==y) return tree[k].pre;
if (tree[k].lazy) down(k,l,r);
int mid=l+r>>;
if (y<=mid) return querypre(tree[k].l,l,mid,x,y);
else if (x>mid) return querypre(tree[k].r,mid+,r,x,y);
else return querypre(tree[k].l,l,mid,x,mid)+querypre(tree[k].r,mid+,r,mid+,y)+1ll*querys(tree[k].l,l,mid,x,mid)*(y-mid);
}
void ins(int &k,int l,int r,int x,int y)
{
//cout<<l-n<<' '<<r-n<<' '<<x-n<<' '<<y-n<<endl;
if (!k) k=++cnt;
if (l==x&&r==y) {update(k,l,r,);return;}
if (tree[k].lazy) down(k,l,r);
int mid=l+r>>;
if (y<=mid) ins(tree[k].l,l,mid,x,y);
else if (x>mid) ins(tree[k].r,mid+,r,x,y);
else ins(tree[k].l,l,mid,x,mid),ins(tree[k].r,mid+,r,mid+,y);
tree[k].sum=tree[tree[k].l].sum+tree[tree[k].r].sum;
tree[k].pre=tree[tree[k].l].pre+tree[tree[k].r].pre+1ll*tree[tree[k].l].sum*(r-mid);
}
int main()
{
#ifndef ONLINE_JUDGE
freopen("bzoj5110.in","r",stdin);
freopen("bzoj5110.out","w",stdout);
const char LL[]="%I64d\n";
#else
const char LL[]="%lld\n";
#endif
n=read();read();
for (int i=;i<=n;i++)
{
a[i]=read()+;
if (!p[a[i]]) ins(root[a[i]],,n*,n+-i,n);
nxt[p[a[i]]]=i,p[a[i]]=i;
}
for (int i=;i<=n;i++) if (!nxt[i]) nxt[i]=n+;
for (int i=;i<=n;i++)
{
f[a[i]]++;
int x=*f[a[i]]-(nxt[i]-),y=*f[a[i]]-i;
ans+=1ll*querys(root[a[i]],,n*,,n+x-)*(y-x+);
ans+=querypre(root[a[i]],,n*,n+x-,n+y-);
ins(root[a[i]],,n*,x+n,y+n);
}
cout<<ans;
return ;
}
BZOJ5110 CodePlus2017Yazid 的新生舞会(线段树)的更多相关文章
- 【BZOJ5110】[CodePlus2017]Yazid 的新生舞会 线段树
[BZOJ5110][CodePlus2017]Yazid 的新生舞会 Description Yazid有一个长度为n的序列A,下标从1至n.显然地,这个序列共有n(n+1)/2个子区间.对于任意一 ...
- BZOJ.5110.[CodePlus2017]Yazid 的新生舞会(线段树/树状数组/分治)
LOJ BZOJ 洛谷 又来发良心题解啦 \(Description\) 给定一个序列\(A_i\).求有多少个子区间,满足该区间众数出现次数大于区间长度的一半. \(n\leq5\times10^5 ...
- 「CodePlus 2017 11 月赛」Yazid 的新生舞会(树状数组/线段树)
学习了新姿势..(一直看不懂大爷的代码卡了好久T T 首先数字范围那么小可以考虑枚举众数来计算答案,设当前枚举到$x$,$s_i$为前$i$个数中$x$的出现次数,则满足$2*s_r-r > 2 ...
- [BZOJ5110]Yazid的新生舞会
题目大意: 给你一个长度为$n(n\leq 5\times 10^5)$的序列$A_{1\sim n}$.求满足区间众数在区间内出现次数严格大于$\lfloor\frac{r-l+1}{2}\rflo ...
- luogu P4062 [Code+#1]Yazid 的新生舞会(线段树+套路)
今天原来是平安夜啊 感觉这题是道好题. 一个套路枚举权值\(x\),把权值等于\(x\)的设为1,不等于的设为-1,然后问题转化为多少个区间权值和大于. 发现并不是很好做,还有一个套路,用前缀和查分来 ...
- 【线段树】【P4062】 [Code+#1]Yazid 的新生舞会
Description 给定一个长度为 \(n\) 的序列,求有多少子区间满足区间众数严格大于区间长度的一半.如果区间有多个出现次数最多且不同的数则取较小的数为众数. Limitation 对于全部的 ...
- 洛谷 P4062 - [Code+#1]Yazid 的新生舞会(权值线段树)
题面传送门 题意: 给出一个序列 \(a\),求 \(a\) 有多少个子区间 \([l,r]\),满足这个区间中出现次数最多的数出现次数 \(>\dfrac{r-l+1}{2}\) \(1 \l ...
- 【bzoj5110】Yazid的新生舞会
这里是 $THUWC$ 选拔时间 模拟赛的时候犯 $SB$ 了,写了所有的部分分,然后直接跑过了 $4$ 个大样例(一个大样例是一个特殊情况)…… 我还以为我非常叼,部分分都写对了,于是就不管了…… ...
- bzoj5110: [CodePlus2017]Yazid 的新生舞会
Description Yazid有一个长度为n的序列A,下标从1至n.显然地,这个序列共有n(n+1)/2个子区间.对于任意一个子区间[l,r] ,如果该子区间内的众数在该子区间的出现次数严格大于( ...
随机推荐
- 富文本编辑器 wangEditor.js
1.引用 wangEditor 相关js 和 css 下载地址:https://files.cnblogs.com/files/kitty-blog/WangEditor.zip 3.页面: < ...
- 基于webSocket的聊天室
前言 不知大家在平时的需求中有没有遇到需要实时处理信息的情况,如站内信,订阅,聊天之类的.在这之前我们通常想到的方法一般都是采用轮训的方式每隔一定的时间向服务器发送请求从而获得最新的数据,但这样会浪费 ...
- Python函数中的参数
形参:形式参数 实参:实际参数 1.普通参数:严格按照顺序将实参赋值给形参. 2.默认参数:必须放置在参数列表的最后. 3.指定参数:将实参赋值给制定参数. 4.动态参数: *:默认将传入的参数,全部 ...
- go执行外部应用
go执行外部应用 最近想将原来用asp.net mvc写的一个公司内部网站改用beego来写,但发现其中有一个功能是,能将加密的sqlite文件进行解密,因为这个解密是不能公开的,但有些同事需要查看这 ...
- 48-Identity MVC:Model前后端验证
1-创建RegisterViewModel类 namespace MvcCookieAuthSample.ViewModel { public class RegisterViewModel { [R ...
- 基于Ubuntu Server 16.04 LTS版本安装和部署Django之(一):安装Python3-pip和Django
近期开始学习基于Linux平台的Django开发,想配置一台可以发布的服务器,经过近一个月的努力,终于掌握了基于Apache和mod-wsgi插件的部署模式,自己也写了一个教程,一是让自己有个记录,二 ...
- 详解mysql体系结构和存储引擎
概述 之前整理的一些mysql方面内容,适合做备忘,因为我基本不会去记这些概念性的东西,大家做个了解就可以了. 一.定义数据库和实例 1.数据库: 物理操作系统文件或其他形式文件类型的集合. 在MyS ...
- CentOS 7 systemd添加自定义系统服务
systemd: CentOS 7的服务systemctl脚本存放在:/usr/lib/systemd/,有系统(system)和用户(user)之分,即:/usr/lib/systemd/syste ...
- 使用maven插件生成grpc所需要的Java代码
1.首先需要编写自己需要的.proto文件,本文重点不在这里,.proto可以参考grpc官方例子 https://grpc.io/docs/quickstart/java.html 2.创建自己的J ...
- 菜鸟级appium 必看
之所以写这个,因为太多新人,appium环境半天都搭建不好,版本问题,兼容问题等等. 自己的解决方案:1 官网下载nodejs,建议安装长期支持版 2 进入appium官网,点击下载,跳转到githu ...