• 我最近是不是数据结构学傻了啊。。。
  • 这道题看是1e5,所以复杂度为\(O(nlogn)\)的是完全可以跑过去的,然后看题,要求的对于每个数满足要求的区间的长度之和,我们自然而然的就可以想到用FHQ-Treap来维护这个序列了。

- ps:不会FHQ的小伙伴们可以学习一下,这也是一个比较好用的数据结构(特别是打暴力)。

  • 然后事情就很好办了。先建一个一颗平衡树,然后每次查询的时候直接用我们可奈的split操作分出满足条件的区间,然后直接统计答案即可。
  • 但是有一个小小的问题,我们每次分出来的序列没有包含与这个相同的数,但它们也是要统计进去的,怎么办呢?

    map,你值得拥有!
  • 我们可以用map记录一下每个出现的次数,相同的数之间形成的匹配数为$ \frac {n*(n-1)}{2} $,因为每个数只能用一次,所以算过了之后要归0;
  • 基本思路就是这样,还有一些处理上的小细节,我会在代码中指出。

AC CODE:

#include<bits/stdc++.h>
#define clean(a,i) memset(a,i,sizeof(a))
#define ll long long
#define inl inline
#define il inl void
#define it inl int
#define ill inl ll
#define re register
#define ri re int
#define rl re ll
#define lc(cur) ch[cur][0]
#define rc(cur) ch[cur][1]
using namespace std;
template<class T>il read(T &x)
{
int f=1;char k=getchar();x=0;
for(;k>'9'||k<'0';k=getchar()) if(k=='-') f=-1;
for(;k>='0'&&k<='9';k=getchar()) x=(x<<3)+(x<<1)+k-'0';
x*=f;
}
const int MAXN = 1e5+5;
// 下方为FHQ-Treap的基本操作
int n,a[MAXN],ch[MAXN][2],val[MAXN],size[MAXN],rd[MAXN],cnt;
il pushup(int cur){size[cur]=size[lc(cur)]+size[rc(cur)]+1;}
it new_node(int a){
val[++cnt]=a,size[cnt]=1,rd[cnt]=rand();
return cnt;
}
it merge(int x,int y){
if(!x||!y) return x+y;
if(rd[x]<rd[y]){
rc(x)=merge(rc(x),y);
pushup(x);return x;
}
else{
lc(y)=merge(x,lc(y));
pushup(y);return y;
}
}
il split(int cur,int k,int &x,int &y){
if(!cur) x=y=0;
else{
if(val[cur]<=k) x=cur,split(rc(x),k,rc(x),y);
else y=cur,split(lc(y),k,x,lc(y));
pushup(cur);
}
}
int root,x,y,z;
il insert(int val){split(root,val,x,y),root=merge(merge(x,new_node(val)),y);}
//打板子时间到此为止,下面是具体的一些操作细节
map<int,int> mp;//用来储存每个数出现的个数
ll ans;//注意要开longlong
int main()
{
read(n);
for(ri i=1;i<=n;i++) read(a[i]),mp[a[i]]++,insert(a[i]);//读入数据,对每个数的出现进行储存,顺便将这个节点插入到平衡树里
for(ri i=1;i<=n;i++){
ri t=a[i]*9/10;
if(a[i]%10==0) t-=1;//这里的两步要注意下,我就是在这里死了好几次。首先是要先乘再除,这样可以保证精度。然后是后面的if判断,通过打表(或者直接推)可以发现,只有10的倍数乘上0.9才是一个整数。因为我们要将小于它的数中满足条件的分成两部分,所以为正数的时候边界还要左移(不太懂的可以自己举几个栗子,或者自己感性理解一下(逃))
split(root,a[i]-1,x,z),split(x,t,x,y);
ans+=size[y],root=merge(merge(x,y),z);//这里的两部都是FHQ的正常操作,顺带着统计下答案
}
for(ri i=1;i<=n;i++){
ri sz=mp[a[i]];mp[a[i]]=0;//把每一个还没有计算过的数拿出来统计答案,级的统计过后要归0
if(!sz) continue;
ans+=1LL*sz*(sz-1)/2;
}
printf("%lld",ans);
return 0;
}

最后再温馨提示一下,蒟蒻的这种做法其实并不是最优的,这道题可以做到O(n),如果感兴趣可以看一下我的方法,但最优的解法还是要学习一下的

Luogu P4670 [BalticOI 2011 Day2]Plagiarism 题解的更多相关文章

  1. Luogu 4784 [BalticOI 2016 Day2]城市

    斯坦纳树复习,我暑假的时候好像写过[JLOI2015]管道连接来着. 设$f_{i, s}$表示以$i$为根,$k$个重要点的连通状态为$s$,($0$代表没有连进最小生成树里面去,$1$代表连进了最 ...

  2. LOJ#2632. 「BalticOI 2011 Day1」打开灯泡 Switch the Lamp On

    题目描述 译自 BalticOI 2011 Day1 T3「Switch the Lamp On」有一种正方形的电路元件,在它的两组相对顶点中,有一组会用导线连接起来,另一组则不会.有 N×M 个这样 ...

  3. SCOI 2015 Day2 简要题解

    「SCOI2015」小凸玩密室 题意 小凸和小方相约玩密室逃脱,这个密室是一棵有 $ n $ 个节点的完全二叉树,每个节点有一个灯泡.点亮所有灯泡即可逃出密室.每个灯泡有个权值 $ A_i $,每条边 ...

  4. 【GDOI 2011 DAY2 T3】零什么的最讨厌了 (快速求阶乘、中国剩余定理)

    问题描述: 林记在做数学习题的时候,经常遇到这种情况:苦思冥想了很久终于把问题解出来,结果发现答案是0,久而久之林记在得到习题答案是0的时候就没有了做出一道难题的成就感.于是林记决定:以后出题,答案一 ...

  5. JLOI2015 DAY2 简要题解

    「JLOI2015」骗我呢 题意 问有多少个 \(n \times m\) 的矩阵 \(\{x_{i, j}\}\) 满足 对于 \(\forall i \in [1, n], j \in [1, m ...

  6. SCOI2016 Day2 简要题解

    「SCOI2016」妖怪 题意 有 \(n\) 只妖怪,每只妖怪有攻击力 \(\text{atk}\) 和防御力 \(\text{dnf}\) ,在环境 \((a, b)\) 下,它可以把攻击力和防御 ...

  7. 【luogu P1955 [NOI2015]程序自动分析】 题解

    题目链接:https://www.luogu.org/problemnew/show/P1955 并查集操作,1e9要离散化,数组要开大一些,操作前先执行合并操作 样例好毒啊(全是排好序的) #inc ...

  8. 【luogu P2195 HXY造公园】 题解

    题目链接:https://www.luogu.org/problemnew/show/P2195 fir.吐槽题目(省略1w字 sec.考虑对一个森林的维护,每棵树用并查集维护. 操作1:输出当前查询 ...

  9. 【luogu P1073 最优贸易】 题解

    题目链接:https://www.luogu.org/problemnew/show/P1073 对于状态量相互影响的题目,分层图是个不错的想法. 考虑在题目中分为: 不交易: 直接从1到n出去,为0 ...

随机推荐

  1. jdk更换不起作用问题

    本人前面装了jdk8,现在准备用jdk7,我安装好了jdk7:把系统变量中的JAVA_HOME 改为 D:\java\jdk\jdk7\jdk1.7.0_67,Path 下添加如下变量,记得加;和上一 ...

  2. mac windows蓝牙问题

    如果是win7.win8或win10三者的64位版本,可以下载驱动解决:http://file2.mydrivers.com/2014/notebook/apple_broadcom_bluetoot ...

  3. spring AbstractRoutingDataSource实现动态数据源切换

    使用Spring 提供的 AbstractRoutingDataSource 实现 创建 AbstractRoutingDataSource 实现类,负责保存所有数据源与切换数据源策略:public ...

  4. Javascript 中函数的 length 属性

    每个函数都有一个 length属性 (函数名.length), 表示期望接收的函数的个数(而不是实际接收的参数个数) 它与arguments不同. arguments.length 是表示函数实际接收 ...

  5. _RecordsetPtr使用方法

    _variant_t vUsername,vID,vname; //变量声明 _RecordsetPtr m_pRecordset;     //记录集 CString strid; _Connect ...

  6. Android DalivkVM与JVM的比较

    JVM 与 DalivkVM的区别 Android 为什么还有搞一个Dalivk虚拟机,不是已经就有Java虚拟机了吗,为什么还要专门搞一个Dalivk虚拟机呢? 答: 1.以前Java是Sun公司的 ...

  7. Metronic-最优秀的基于Bootstrap的响应式网站模版

    在所有我看到过的基于Bootstrap的网站模版中,Metronic是我认为最优秀的,其外观之友好.功能之全面让人惊叹.Metronic 是一个自适应的HTML模版,提供后台管理模版和前端内容网页模版 ...

  8. 排序算法之堆排序(Heapsort)解析

    一.堆排序的优缺点(pros and cons) (还是简单的说说这个,毕竟没有必要浪费时间去理解一个糟糕的的算法) 优点: 堆排序的效率与快排.归并相同,都达到了基于比较的排序算法效率的峰值(时间复 ...

  9. 从 exe.config 读取appSettings 中的配置数据

    右键解决方案,添加引用--> System.Configuration.dll 在exe.config 中添加数据 <appSettings> <add key=" ...

  10. update from用法

    from:https://www.cnblogs.com/zerocc/archive/2011/11/01/2231841.html update 表名 SET  更新字段 FROM 更新表名(多个 ...