题目传送门(内部题67)


输入格式

第一行,三个整数$n$、$k$、$p$。
第二行,$n$个自然数,表示$\{a_i\}$。


输出格式

输出一行,两个自然数,表示$f(res)$、$res$。


样例

样例输入1:

4 3 5
2 0 3 7

样例输出1:

4 4

样例输入2:

2 2 1
2 0

样例输出2:

0 2


数据范围与提示

本题有$spj$,输出格式正确的情况下,仅回答正确$f(res)$、$res$中的一个可以获得$60\%$的分数(向下取整)。


题解

考虑怎样才能形成逆序对,或怎样才能让本身的逆序对消失。

设$a,b$,将其分解为二进制,我们只有改变其最高的不同位才能改变其大小关系;若对于其最高的不同位$a$为$0$,$b$为$1$,那么如果$xor$一个这一位是$1$的数,则其大小关系会改变,反之同理。

所以考虑$Trie$,将每一个$a_i$分解成二进制插入并计算贡献即可。

这样的算法是$55$分的。

考虑如何优化,部分正确提示了可以二分。

二分逆序对的个数即可,最后再用二分出来的值返回去找$res$即可。

时间复杂度:$\Theta(\log n^2\times 2^{\frac{k}{2}})$。

期望得分:$100$分。

实际得分:$100$分。


代码时刻

#include<bits/stdc++.h>
using namespace std;
int k;
long long n,p;
int trie[20000000][2],cnt=1;
long long sum[20000000][2],num[20000000];
long long ans;
long long val;
long long que[3000001];
pair<long long,int> f1[3000001],f2[3000001];
void insert(int x)
{
int p=0;
for(int i=k-1;i>=0;i--)
{
if(!trie[p][(x>>i)&1])trie[p][(x>>i)&1]=++cnt;
sum[i][(x>>i)&1]+=num[trie[p][((x>>i)&1)^1]];
p=trie[p][(x>>i)&1];
num[p]++;
}
}
bool judge(long long x)
{
long long res=0;
int fail=(1<<(k-k/2));
for(int i=0;i<(1<<(k/2))&&f1[i].first<=x;i++)
{
while(x-f1[i].first<=f2[fail-1].first&&fail)fail--;
res+=fail;
}
if(res<p){val=res;return 1;}
return 0;
}
long long getans()
{
int fail=(1<<(k-k/2))-1;
for(int i=0;i<(1<<(k/2))&&f1[i].first<=ans;i++)
{
long long x=ans-f1[i].first;
while(x<f2[fail].first&&fail>=0)fail--;
if(f2[fail].first==x)que[++que[0]]=f1[i].second+(1<<(k/2))*f2[fail].second;
}
sort(que+1,que+que[0]+1);
return que[p-val];
}
int main()
{
scanf("%lld%d%lld",&n,&k,&p);
for(int i=1;i<=n;i++)
{
int x;
scanf("%d",&x);
insert(x);
}
for(int i=0;i<(1<<(k/2));i++)
{
for(int j=0;j<(k/2);j++)f1[i].first+=sum[j][i>>j&1];
f1[i].second=i;
}
for(int i=0;i<(1<<(k-k/2));i++)
{
for(int j=0;j<(k-k/2);j++)f2[i].first+=sum[j+k/2][i>>j&1];
f2[i].second=i;
}
sort(f1,f1+(1<<(k/2)));
sort(f2,f2+(1<<(k-k/2)));
long long lft=0,rht=n*(n-1)/2;
while(lft<=rht)
{
long long mid=(lft+rht)>>1;
if(judge(mid)){lft=mid+1;ans=mid;}
else rht=mid-1;
}
printf("%lld %lld",ans,getans());
return 0;
}

rp++

[CSP-S模拟测试]:f(Trie树+二分答案+meet in middle+two pointers)的更多相关文章

  1. 洛谷P4344 脑洞治疗仪 [SHOI2015] 线段树+二分答案/分块

    !!!一道巨恶心的数据结构题,做完当场爆炸:) 首先,如果你用位运算的时候不小心<<打成>>了,你就可以像我一样陷入疯狂的死循环改半个小时 然后,如果你改出来之后忘记把陷入死循 ...

  2. [BZOJ 2653] middle(可持久化线段树+二分答案)

    [BZOJ 2653] middle(可持久化线段树+二分答案) 题面 一个长度为n的序列a,设其排过序之后为b,其中位数定义为b[n/2],其中a,b从0开始标号,除法取下整. 给你一个长度为n的序 ...

  3. 2018.10.20 NOIP模拟 巧克力(trie树+dfs序+树状数组)

    传送门 好题啊. 考虑前面的32分,直接维护后缀trietrietrie树就行了. 如果#号不在字符串首? 只需要维护第一个#前面的字符串和最后一个#后面的字符串. 分开用两棵trie树并且维护第一棵 ...

  4. BZOJ3166 [Heoi2013]Alo 【可持久化trie树 + 二分 + ST表】

    题目 Welcome to ALO ( Arithmetic and Logistic Online).这是一个VR MMORPG , 如名字所见,到处充满了数学的谜题. 现在你拥有n颗宝石,每颗宝石 ...

  5. 4.15 省选模拟赛 编码 trie树 前缀和优化建图 2-sat

    好题 np. 对于20分 显然可以爆搜. 对于50分 可以发现每个字符串上的问号要么是0,要么是1.考虑枚举一个字符串当前是0还是1 这会和其他字符串产生矛盾. 所以容易 发现这是一个2-sat问题. ...

  6. [CSP-S模拟测试]:中间值(二分)

    题目背景 $Maxtir$喜欢序列的中间值. 题目传送门(内部题127) 输入格式 第一行输入两个正整数$n,m$,其中$m$是操作和询问次数. 接下来两行每行输入$n$个非负整数,每一行分别表示两个 ...

  7. BZOJ1758[Wc2010]重建计划——分数规划+长链剖分+线段树+二分答案+树形DP

    题目描述 输入 第一行包含一个正整数N,表示X国的城市个数. 第二行包含两个正整数L和U,表示政策要求的第一期重建方案中修建道路数的上下限 接下来的N-1行描述重建小组的原有方案,每行三个正整数Ai, ...

  8. 【bzoj2653】【middle】【主席树+二分答案】

    Description 一个长度为 n 的序列 a ,设其排过序之后为 b ,其中位数定义为 b[n/2] ,其中 a,b 从 0 开始标号 , 除法取下整. 给你一个长度为 n 的序列 s .回答 ...

  9. 洛谷P4632 [APIO2018] New Home 新家(动态开节点线段树 二分答案 扫描线 set)

    题意 题目链接 Sol 这题没有想象中的那么难,但也绝对不简单. 首先把所有的询问离线,按照出现的顺序.维护时间轴来处理每个询问 对于每个询问\((x_i, y_i)\),可以二分答案\(mid\). ...

随机推荐

  1. [Web 前端] 021 js 初识 Javascript

    1. Javascript 简介 1.1 定位 JS 是运行在浏览器端的脚本语言 1.1.1 关于浏览器 JS 由浏览器解释执行 JS 通常被直接嵌入 HTML 页面 1.1.2 关于脚本语言 JS ...

  2. steps 步骤条、时间轴

    steps 步骤条.时间轴:http://www.fxss5201.cn/project/plugin/steps/1.0/ Github地址:https://github.com/fxss5201/ ...

  3. 程序员听到bug后的N种反应…

    程序员的世界里, 不止有代码, 还有bug,bug,bug- 当出现bug时, 程序员们的反应是怎样的呢? 作者:苏小喵,来源:小花小画(微信号:hua-little) - END - 推荐阅读: 1 ...

  4. swtich和case语句中,定义变量要加花括号

    转自: http://blog.chinaunix.net/uid-27103408-id-3340702.html http://www.xuebuyuan.com/2070170.html swi ...

  5. 6.float类型 和 char 类型

    float32  float64 package main import "fmt" func main() { var xxx float32 var xxxx float64 ...

  6. [LeetCode] 45. 跳跃游戏 II

    题目链接 : https://leetcode-cn.com/problems/jump-game-ii/ 题目描述: 给定一个非负整数数组,你最初位于数组的第一个位置. 数组中的每个元素代表你在该位 ...

  7. 为什么要用消息队列 及 自己如何设计一个mq架构

    1. 解耦:如左图, 系统a因为业务需求需要调用系统b,后续因为业务需求可能需要改代码调用系统c,甚至还要考虑被调用的系统挂了访问超时的问题.耦合性太高! 如右图, 系统a产生一条数据发送到消息队列里 ...

  8. Mysql逻辑架构介绍

    总体概览: 和其它数据库相比,MySQL有点与众不同,它的架构可以在多种不同场景中应用并发挥良好作用.主要体现在存储引擎的架构上,插件式的存储引擎架构将查询处理和其它的系统任务以及数据的存储提取相分离 ...

  9. SPSS Statistics 26.0 下载安装和激活

    目录 1. 其他版本 2. IBM SPSS Statistics 26 新增功能 3. 安装步骤 4. 下载地址 1. 其他版本 参考:https://www.cnblogs.com/coco56/ ...

  10. 通过关键字Event定义用户自己的事件

    Event 语句 定义用户自定义的事件. 语法[Public] Event procedurename [(arglist)] Event 语句包含下面部分: 部分 描述 Public 可选的.指定该 ...