先考虑部分分(只有01/只有0~7)做法:枚举每个数,把和他相同的设为1,不同的设为-1,然后这个数作为众数贡献的个数就是区间和>0的个数

推着做,树状数组记前缀和<=x的区间的数量就可以,复杂度$O(8nlogn)$

如果直接套过来,$O(n^2logn)$肯定是不行的,但可以发现枚举了所有数以后1的个数一共只能有n个,而如果把相邻的-1看成一个,它的数量也是O(n)的

所以对于1的做法是不变的;对于-1,我们要连起来处理。如果设这段-1之前的和为sum,-1的个数为len可以得到这段-1的贡献,其实就是$[-n,sum-len-1]+[-n,sum-len]+...+[-n,sum-2]$(我们用一个权值线段树来记前缀和为某值的数量)

为了方便计算,做一个前缀和,就变成了

$$\sum\limits_{i=-n}^{sum-2}{\sum\limits_{j=-n}^{i}{a[j]}}-\sum\limits_{i=-n}^{sum-len-2}{\sum\limits_{j=-n}^{i}{a[j]}}$$

(可以看出与树状数组做区间加、区间求和的操作类似)

$$=(sum-2+1)\sum\limits_{i=-n}^{sum-2}{a[i]}-\sum\limits_{i=-n}^{sum-2}{i*a[i]}-((sum-len-2+1)\sum\limits_{i=-n}^{sum-len-2}{a[i]}-\sum\limits_{i=-n}^{sum-len-2}{i*a[i]})$$

然后用线段树维护a[i]和i*a[i]就可以了。而且我们每次枚举完一个以后不能直接memset,不然就变成O(n^2)了,要怎么加进来的就怎么减回去..

(然后我bzoj上就T了,肯定是评测机太卡了)

  1. #define __Ressed__ <bits/stdc++.h>
  2. #include __Ressed__
  3. #define pa pair<int,int>
  4. #define lowb(x) ((x)&(-(x)))
  5. #define REP(i,n0,n) for(i=n0;i<=n;i++)
  6. #define PER(i,n0,n) for(i=n;i>=n0;i--)
  7. #define MAX(a,b) ((a>b)?a:b)
  8. #define MIN(a,b) ((a<b)?a:b)
  9. #define CLR(a,x) memset(a,x,sizeof(a))
  10. #define rei register int
  11. using namespace std;
  12. typedef long long ll;
  13. const int maxn=5e5+;
  14.  
  15. inline ll rd(){
  16. ll x=;char c=getchar();int neg=;
  17. while(c<''||c>''){if(c=='-') neg=-;c=getchar();}
  18. while(c>=''&&c<='') x=x*+c-'',c=getchar();
  19. return x*neg;
  20. }
  21.  
  22. ll v[maxn*],iv[maxn*],laz[maxn*],ans;
  23. int ch[maxn*][],pct,root;
  24. int nxt[maxn],hd[maxn];
  25. int L,N,M,num[maxn],tmp[maxn];
  26.  
  27. inline void pushdown(int p,int l,int r){
  28. int m=l+r>>,a=ch[p][],b=ch[p][];
  29. if(a){
  30. laz[a]+=laz[p];
  31. v[a]+=laz[p]*(m-l+);
  32. iv[a]+=laz[p]*(m+l)*(m-l+)/;
  33. }
  34. if(b){
  35. laz[b]+=laz[p];
  36. v[b]+=laz[p]*(r-m);
  37. iv[b]+=laz[p]*(r+m+)*(r-m)/;
  38. }
  39. laz[p]=;
  40. }
  41.  
  42. inline void update(int p){
  43. v[p]=v[ch[p][]]+v[ch[p][]];
  44. iv[p]=iv[ch[p][]]+iv[ch[p][]];
  45. }
  46.  
  47. void build(int &p,int l,int r){
  48. if(!p) p=++pct;
  49. if(l<r){
  50. int m=l+r>>;
  51. build(ch[p][],l,m);
  52. build(ch[p][],m+,r);
  53. }
  54. }
  55.  
  56. inline void add(int p,int l,int r,int x){
  57. laz[p]+=x;
  58. v[p]+=1ll*(r-l+)*x;
  59. iv[p]+=1ll*(r+l)*(r-l+)/*x;
  60. pushdown(p,l,r);
  61. }
  62.  
  63. void ins(int p,int l,int r,int x,int y,int z){
  64. if(x<=l&&r<=y){
  65. add(p,l,r,z);
  66. }else{
  67. pushdown(p,l,r);
  68. int m=l+r>>;
  69. if(x<=m) ins(ch[p][],l,m,x,y,z);
  70. if(y>=m+) ins(ch[p][],m+,r,x,y,z);
  71. update(p);
  72. }
  73. }
  74.  
  75. ll query(int p,int l,int r,int x){
  76. pushdown(p,l,r);
  77. if(r<=x){
  78. return v[p]*(x+)-iv[p];
  79. }else{
  80. int m=l+r>>;ll re;
  81. re=query(ch[p][],l,m,x);
  82. if(x>=m+) re+=query(ch[p][],m+,r,x);
  83. return re;
  84. }
  85. }
  86.  
  87. ll query2(int p,int l,int r,int x){
  88. if(r<=x){
  89. return v[p];
  90. }else{
  91. pushdown(p,l,r);
  92. int m=l+r>>;ll re;
  93. re=query2(ch[p][],l,m,x);
  94. if(x>=m+) re+=query2(ch[p][],m+,r,x);
  95. return re;
  96. }
  97. }
  98.  
  99. int main(){
  100. // freopen("6253.in","r",stdin);
  101. rei i,j,k;
  102. N=rd();rd();
  103. for(i=;i<=N;i++) tmp[i]=num[i]=rd();
  104. sort(tmp+,tmp+N+);M=unique(tmp+,tmp+N+)-tmp-;
  105. for(i=;i<=N;i++) num[i]=lower_bound(tmp+,tmp+M+,num[i])-tmp;
  106. for(i=N;i;i--){
  107. nxt[i]=hd[num[i]];hd[num[i]]=i;
  108. }
  109. L=N+;
  110. build(root,-L,L);
  111. ins(root,-L,L,,,);
  112. for(i=;i<=M;i++){
  113. int sum=;
  114. for(j=hd[i],k=;j;j=nxt[j]){
  115. if(k<j){
  116. ans+=query(root,-L,L,sum-)-query(root,-L,L,sum-j+k-);
  117. ins(root,-L,L,sum-j+k,sum-,);
  118. sum-=j-k;
  119. }sum++;
  120. ans+=query2(root,-L,L,sum-);
  121. ins(root,-L,L,sum,sum,);
  122. k=j+;
  123. }
  124. ans+=query(root,-L,L,sum-)-query(root,-L,L,sum-N+k-);
  125. sum=;
  126. for(j=hd[i],k=;j;j=nxt[j]){
  127. if(k<j){
  128. ins(root,-L,L,sum-j+k,sum-,-);
  129. sum-=j-k;
  130. }sum++;
  131. ins(root,-L,L,sum,sum,-);
  132. k=j+;
  133. }
  134. }
  135. printf("%lld\n",ans);
  136. return ;
  137. }

loj6253/luogu4062-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. 【bzoj5110】Yazid的新生舞会

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

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

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

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

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

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

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

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

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

  9. [BZOJ5110]Yazid的新生舞会

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

  10. bzoj 5110 Yazid的新生舞会

    题目大意: 一个数列,求有多少个区间$[l,r]$满足该区间的众数出现次数大于$\lceil \frac{r-l}{2} \rceil$ 思路: 对于一个区间满足条件的众数明显是唯一的 所以设该数的前 ...

随机推荐

  1. Scala _ 下划线

    1.引入包中的全部方法 import math._ //引入包中所有方法,与java中的*类似 2.表示集合元素 val a = (1 to 10).filter(_%2==0).map(_*2) / ...

  2. maven中添加jetty运行插件

            maven项目,用jetty插件运行,对热部署的支持比较好.maven的pom文件加入下面代码 <plugin> <groupId>org.mortbay.je ...

  3. python基础学习1-流程控制和判断

    python for循环和 if流程控制用法 Ages=22 for i in range(10): inputAges = int(input("输入年龄")) if input ...

  4. python高并发和多线程的关系

    “高并发和多线程”总是被一起提起,给人感觉两者好像相等,实则 高并发 ≠ 多线程 多线程是完成任务的一种方法,高并发是系统运行的一种状态,通过多线程有助于系统承受高并发状态的实现.   高并发是一种系 ...

  5. LeetCode Container With Most Water (Two Pointers)

    题意 Given n non-negative integers a1, a2, ..., an, where each represents a point at coordinate (i, ai ...

  6. anaconda安装opencv3

    opencv是C和C++语言编写的,很多教程都是基于C++语言进行学习的,可是机器学习最多的库是python写的,所以还是学学python怎么安装opencv3, 面向学习的大都是使用了anacond ...

  7. [Direct2D开发] 绘制网格

    转载请注明出处:http://www.cnblogs.com/Ray1024 一.引言 最近在使用Direct2D进行绘制工作中,需要实现使用Direct2D绘制网格的功能.在网上查了很多资料,终于实 ...

  8. Ing_制作在线QQ

    制作在线QQ的具体步骤 1.首先登录到http://is.qq.com/webpresence/code.shtml 网站2.选择风格3.填写相关数据4.生成网页代码5.复制代码到“写字板”,另存文件 ...

  9. js的各种正则表达式

    验证各种手机包括成都"028-"开头的座机号验证 if (!(/^(16[8]|13[0-9]|15[0|3|6|7|8|9]|18[7])\d{8}|(028-)\d{7}$/. ...

  10. Unix domain socket 简介

    Unix domain socket 又叫 IPC(inter-process communication 进程间通信) socket,用于实现同一主机上的进程间通信.socket 原本是为网络通讯设 ...