当前位置:网站首页>牛客挑战赛54E题解
牛客挑战赛54E题解
2022-06-22 11:09:00 【caoyang1123】
首先,考虑给定一个非负整数序列,如何求子集可重异或第k小的值。
考虑建出线性基,从高位到低位依次确定子集可重异或第k小的值。设在线性基里面的元素有s个,外面的元素有t个,我们可以发现,不论这t个元素如何选(2^t种方案),它们通过线性基中元素选与不选异或得到的2^s个方案是完全相同的(是线性基能表示的数的个数)。(如,线性基内元素{1,2},线性基外元素{1,3},线性基外元素任何一种选取方案,通过线性基内的不同选取后得到的集合都是{0,1,2,3})
那么从高到低考虑每一位,设这位以下还有x个位在线性基上有值,我们这一位选1就相当于选择的数排名增大(2^x * 2^t),看当前k与该值的大小是否选,然后往下做即可。
现在的问题是要找到序列最短的区间(将b离散化),满足其中子集可重异或第k小值<=给定值。
显然可以发现左端点从小到大枚举,最小可行右端点单调不降。
此时会有一个问题,右端点增大是插入操作可以实现,但是左端点增大是需要删除。
这里有很多方法,出题人将删除操作转化掉,利用线性基大小只有log,且两个线性基能在log^2内合并的性质,用栈维护,大致做法:
设当前考察区间[l,r],维护一个栈s1,栈中每个元素是一个线性基,分别表示[l, rlas]从右到左依次插入得到的后缀线性基和,即某个线性基表示j~las元素(j属于l~rlas)构成的线性基。再维护[rlas+1,r]的当前线性基bas。查询[l,r],将s1栈顶线性基与bas线性基合并后查询第k大;修改:
1)r增大,将新增元素插入线性基bas即可
2)l增大,分两种情况,若l <= rlas,则将s1栈顶元素弹出即可,若l > rlas(即s1栈已空),重构整个栈:新开一个空的线性基,从r到l依次插入元素得到后缀线性基和并压入s1栈,接着将bas清空,变量rlas记为r
显然重构总次数为n,重构总复杂度nlogn,而瓶颈在于查询时合并线性基(log^2每次),总复杂度nlog^2
事实上,出题人认为线性基难以删除,但观摩了下kczno1巨佬的代码,发现线性基是有办法删除元素的(删除最早插入元素)
考虑插入一个元素x失败的情况,等价于此时线性基有一个最小子集S, S能通过异或表示出x。注意到线性基中元素线性无关,故S也为线性无关,且因为S是最小能表示出x的子集,S踢掉一个元素后加入x,S能表示的东西是不会变的。而显然我们扔掉最早的元素一定最优,因此对线性基每个元素维护插入时间,插入失败时,找到该元素的表示集S,把S中插入时间最早元素删除换成x,并把时间记为当前即可。
之后删除l位置时,若线性基存在时间等于l的,那么就一定得删掉了。
具体实现时,可以酱紫写:
void ins(ll x, int y)
{
++tot;
for(int i = 62; i >= 0; i--)
{
if((1LL << i) & x)
{
if(!val[i])
{
val[i] = x;
tim[i] = y;
++cnt;
break;
}
if(y > tim[i])
{
swap(tim[i], y);
swap(val[i], x);
}
x ^= val[i];
}
}
}相当于当前这位元素处于x的表示集中且早于x,直接把线性基上这位值与x互换并更新时间,继续插入操作,显然能实现踢掉最早的那个的效果。
这个做法的复杂度是nlog,比出题人不知道高到哪里去了(XD)
整道题代码:
//#define LOCAL
#include<bits/stdc++.h>
#define pii pair<int,int>
#define fi first
#define sc second
#define pb push_back
#define ll long long
#define trav(v,x) for(auto v:x)
#define all(x) (x).begin(), (x).end()
#define VI vector<int>
#define VLL vector<ll>
#define pll pair<ll, ll>
#define double long double
//#define int long long
using namespace std;
const int N = 1e6 + 100;
const int inf = 1e9;
//const ll inf = 1e18
const ll mod = 998244353;//1e9 + 7
#ifdef LOCAL
void debug_out(){cerr << endl;}
template<typename Head, typename... Tail>
void debug_out(Head H, Tail... T)
{
cerr << " " << to_string(H);
debug_out(T...);
}
#define debug(...) cerr << "[" << #__VA_ARGS__ << "]:", debug_out(__VA_ARGS__)
#else
#define debug(...) 42
#endif
int n, len, num;
pll a[N];
string K;
ll ss;
bool fff = 0;
struct base{
ll val[63];
int tim[63];
int tot, cnt;
void init()
{
memset(val, 0, sizeof val);
memset(tim, 0, sizeof tim);
tot = cnt = 0;
}
void ins(ll x, int y)
{
++tot;
for(int i = 62; i >= 0; i--)
{
if((1LL << i) & x)
{
if(!val[i])
{
val[i] = x;
tim[i] = y;
++cnt;
break;
}
if(y > tim[i])
{
swap(tim[i], y);
swap(val[i], x);
}
x ^= val[i];
}
}
}
void clear(int y)
{
--tot;
for(int i = 62; i >= 0; i--)
{
if(tim[i] == y && val[i])
{
tim[i] = val[i] = 0;
--cnt;
}
}
}
bool chk()
{
ll nw = 0, tmp = tot - cnt, cur = cnt;
if(tot <= len)
return 0;
for(int i = 62; i >= 0; i--)
{
if(val[i])
{
if(K[cur + tmp - 1] == '1')
nw = max(nw, nw ^ val[i]);
else
nw = min(nw, nw ^ val[i]);
--cur;
}
}
return nw <= ss;
}
}bas1;
void sol()
{
cin >> n;
for(int i = 1; i <= n; i++)
{
cin >> a[i].fi >> a[i].sc;
}
sort(a + 1, a + n + 1, [](pll x, pll y)
{
return x.sc < y.sc;
});
cin >> K;
len = K.length() - 1;
reverse(all(K));
cin >> ss;
bas1.init();
ll ans = 1e18;
for(int lp = 1, rp = 0; lp <= n; lp++)
{
if(lp > 1)bas1.clear(lp - 1);
while(rp < n && !bas1.chk())
{
++rp;
bas1.ins(a[rp].fi, rp);
}
if(bas1.chk())
ans = min(ans, a[rp].sc - a[lp].sc);
}
cout << ans << '\n';
}
signed main()
{
ios::sync_with_stdio(0);
cin.tie(0);
// int tt;
// cin >> tt;
// while(tt--)
sol();
}
/*
10
16 272
8 60
1 392
24 352
16 188
1 130
8 161
24 121
24 117
24 156
*/
边栏推荐
- Popular understanding of TCP 3-time handshake
- Cloud minimalist deployment svelte3 chat room
- TCP abnormal connection
- Program architecture design for embedded software development task scheduling
- NFT交易平台数字藏品系统开发技术
- How to improve customer conversion rate on the official website
- 攻防演练 | 基于ATT&CK的威胁狩猎实践案例
- 2022 Shaanxi Provincial Safety Officer C certificate examination question bank simulated examination platform operation
- Install pyGame
- The software used is PHP MySQL database
猜你喜欢

Puzzle (019) plane forward problem

Should the theme of the IDE be bright or dark? Here comes the ultimate answer!

Interpretation of MAML (model agnostic meta learning)

The software used is PHP MySQL database

【软工】 软件体系结构

The father of the college entrance examination student told himself at night that what he cared about most was not the child's performance, and the turning point was not false at all

攻防演练 | 基于ATT&CK的威胁狩猎实践案例
推荐一款M1芯片电脑快速搭建集群的虚拟机软件

NFT交易平台数字藏品系统开发技术

"Dare not doubt the code, but have to doubt the code" a network request timeout analysis
随机推荐
Redis常用命令
初识ElastricSearch
奋斗吧,程序员——第四十四章 八百里分麾下炙,五十弦翻塞外声
Preliminary understanding of AQS
puzzle(019)平面正推问题
Development technology of NFT trading platform digital collection system
Exchange sort method
推薦一款M1芯片電腦快速搭建集群的虛擬機軟件
How many of the eight classic MySQL errors did you encounter?
6-10 global status management - Global store
MySQL lock view
从原型链到继承,图解来龙去脉,推荐收藏
jg_ Using easyexcel to read Excel_ twenty million two hundred and twenty thousand six hundred and nineteen
The first "cyborg" in the world died, and he only transformed himself to "change his life against the sky"
分治思想在海量数据处理中的应用
R language performs two sample t-test on the specified covariates based on the with function, and the t.test function performs Welch two sample t-test analysis and two independent sample t-test on the
6-9 应用间通信 - 子应用通信
【软工】 软件体系结构
Leetcode algorithm The penultimate node in the linked list
R语言使用read.table加载条件logistic回归分析的数据集(csv数据)、使用unique函数查看配对数据有多少组