[CSP-S模拟测试]:f(Trie树+二分答案+meet in middle+two pointers)
题目传送门(内部题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)的更多相关文章
- 洛谷P4344 脑洞治疗仪 [SHOI2015] 线段树+二分答案/分块
!!!一道巨恶心的数据结构题,做完当场爆炸:) 首先,如果你用位运算的时候不小心<<打成>>了,你就可以像我一样陷入疯狂的死循环改半个小时 然后,如果你改出来之后忘记把陷入死循 ...
- [BZOJ 2653] middle(可持久化线段树+二分答案)
[BZOJ 2653] middle(可持久化线段树+二分答案) 题面 一个长度为n的序列a,设其排过序之后为b,其中位数定义为b[n/2],其中a,b从0开始标号,除法取下整. 给你一个长度为n的序 ...
- 2018.10.20 NOIP模拟 巧克力(trie树+dfs序+树状数组)
传送门 好题啊. 考虑前面的32分,直接维护后缀trietrietrie树就行了. 如果#号不在字符串首? 只需要维护第一个#前面的字符串和最后一个#后面的字符串. 分开用两棵trie树并且维护第一棵 ...
- BZOJ3166 [Heoi2013]Alo 【可持久化trie树 + 二分 + ST表】
题目 Welcome to ALO ( Arithmetic and Logistic Online).这是一个VR MMORPG , 如名字所见,到处充满了数学的谜题. 现在你拥有n颗宝石,每颗宝石 ...
- 4.15 省选模拟赛 编码 trie树 前缀和优化建图 2-sat
好题 np. 对于20分 显然可以爆搜. 对于50分 可以发现每个字符串上的问号要么是0,要么是1.考虑枚举一个字符串当前是0还是1 这会和其他字符串产生矛盾. 所以容易 发现这是一个2-sat问题. ...
- [CSP-S模拟测试]:中间值(二分)
题目背景 $Maxtir$喜欢序列的中间值. 题目传送门(内部题127) 输入格式 第一行输入两个正整数$n,m$,其中$m$是操作和询问次数. 接下来两行每行输入$n$个非负整数,每一行分别表示两个 ...
- BZOJ1758[Wc2010]重建计划——分数规划+长链剖分+线段树+二分答案+树形DP
题目描述 输入 第一行包含一个正整数N,表示X国的城市个数. 第二行包含两个正整数L和U,表示政策要求的第一期重建方案中修建道路数的上下限 接下来的N-1行描述重建小组的原有方案,每行三个正整数Ai, ...
- 【bzoj2653】【middle】【主席树+二分答案】
Description 一个长度为 n 的序列 a ,设其排过序之后为 b ,其中位数定义为 b[n/2] ,其中 a,b 从 0 开始标号 , 除法取下整. 给你一个长度为 n 的序列 s .回答 ...
- 洛谷P4632 [APIO2018] New Home 新家(动态开节点线段树 二分答案 扫描线 set)
题意 题目链接 Sol 这题没有想象中的那么难,但也绝对不简单. 首先把所有的询问离线,按照出现的顺序.维护时间轴来处理每个询问 对于每个询问\((x_i, y_i)\),可以二分答案\(mid\). ...
随机推荐
- 红帽学习笔记[RHCSA] 第一课[Shell、基础知识]
关于Shell Shell是什么 Shell是系统的用户界面,提供了用户与内核进行交互操作的一种接口.它接收用户输入的命令并把它送入内核中执行. bash shell是大多数Linux的缺省shell ...
- JS案例经验1
一 可以通过设置在一个div中的多个div的定位属性为absolute,从而使得这几个元素重叠.他们都脱离了标准流. 二 对于absolute的left和right属性,当left和right同时出现 ...
- Linear Discriminant Analysis
Suppose that we model each class density as multivariate Gaussian, in practice we do not know the pa ...
- openmvg中cmd模块解析
---恢复内容开始--- 在openmvg库中,定义了一个CmdLine类来定义例程的输入参数格式.源文件为.\openMVG\src\third_party\cmdLine\cmdLine.h. 先 ...
- linux获取外网ip
引言:目前获取ip的方法中,ifconfig和ip获取函数得到的都是内网ip.有时候需要获取外网ip,目前通用的做法,是向外部服务器发送请求,解析外部服务器响应,从而得到的自己的外网ip.linux下 ...
- python文件打包/导入 .so 文件
打包so文件 见: http://www.cnblogs.com/ke10/p/py2so.html 导入so文件 import sys sys.path.append(r'/home/project ...
- CSS行内框(内联元素)
行内框在一行中水平布置.可以使用水平内边距.边框和外边距调整它们的间距.但是,垂直内边距.边框和外边距不影响行内框的高度.由一行形成的水平框称为行框(Line Box),行框的高度总是足以容纳它包含的 ...
- 一、ASP.NET Iframework_SignalR永久连接类(v2)
一.新建项目,选MVC项目默认 添加mvc文件夹和核心引用 二.添加SignaIR包 SignalR的准备:NuGet包管理器搜索:工具——>库程序包管理器——>Microsoft.Asp ...
- Mongo--04 Mongo分片集群
目录 一.分片的概念 二. 分片工作原理 三.IP端口目录规划 1.IP端口规划 2.目录规划 四.分片集群搭建副本集步骤 1.安装软件 2.创建目录 3.创建配置文件 4.优化警告 5.启动服务 6 ...
- CentOS 7 环境下部署 SVN 并实现自动更新(版本库放在Tomcat下)
1.安装 SVN 1.1先检查是否有安装 svn rpm -qa subversion #没有什么显示就说明没有安装过yum remove subversion #如果有安装就运行删除老版本yum i ...