[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\). ...
随机推荐
- 第十四周总结 Io之文件流
I/O相关 输入/输出 流(数据流动) 数据流动的方向 读数据(输入input) 写数据(输出output) 文件流 字符流 数据流 对象流 网络流.... 1.什么叫文件 一种电脑的存储方式 文件有 ...
- 自定义SpringBoot启动控制台图标
使用过SpringBoot的小伙伴众所周知,在启动的过程中,在控制台会首先打印spring的图标以及版本号(这里以IDEA为例) 如果需要更改这个打印图标的话, 需要以下步骤: 1.打开SpringB ...
- Java IO NIO详细讲解
1.IO Java IO概述 2.NIO Java NIO浅析
- [转帖]IIS7.5应用程序池集成模式和经典模式的区别介绍
IIS7.5应用程序池集成模式和经典模式的区别介绍 之前转帖过一个 但是感觉不如这个说的细: https://www.jb51.net/article/31010.htm 关注脚本之家微信公众号(jb ...
- restful风格详解
一.概念 RESTful架构,就是目前最流行的一种互联网软件架构.它结构清晰.符合标准.易于理解.扩展方便,所以正得到越来越多网站的采用. REST这个词,是Roy Thomas Fielding在他 ...
- linux 进程1
一. 进程的开始和结束 1.1. main函数的调用 a. 编译链接时的引导代码.操作系统下的应用程序其实在main执行前也需要先执行一段引导代码才能去执行main,我们写应用程序时不用考虑引导代码的 ...
- CF682C Alyona and the Tree
题意翻译 题目描述 给你一棵树,边与节点都有权值,根节点为1,现不停删除叶子节点形成新树,问最少删掉几个点,能使得最后剩下的树内,∀v与其子树内∀u间边权的和小于点u权值 输入输出格式 输入格式: 第 ...
- 配置多个broker
前言 什么是kafka?举个例子,生产者消费者,生产者生产鸡蛋,消费者消费鸡蛋,生产者生产一个鸡蛋,消费者就消费一个鸡蛋,假设消费者消费鸡蛋的时候噎住了(系统宕机了),生产者还在生产鸡蛋,那新生产的鸡 ...
- python中,a=10.0 b=10.0 a is b 为什么输出是false
>>>a=10.0>>>b=10.0>>>a is bFalse为什么当a=10,b=10时,a is b输出的是True呢? >>& ...
- mysqldump: [Warning] Using a password on the command line interface can be insecure.
MySQL 5.6 警告信息 command line interface can be insecure 修复 在命令行输入密码,就会提示这些安全警告信息. Warning: Using a pas ...