惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

有赞技术团队
有赞技术团队
MyScale Blog
MyScale Blog
Cyberwarzone
Cyberwarzone
Schneier on Security
Schneier on Security
I
Intezer
Cisco Talos Blog
Cisco Talos Blog
Cloudbric
Cloudbric
Exploit-DB.com RSS Feed
Exploit-DB.com RSS Feed
NISL@THU
NISL@THU
博客园 - Franky
F
Fortinet All Blogs
Google DeepMind News
Google DeepMind News
Jina AI
Jina AI
T
The Exploit Database - CXSecurity.com
P
Proofpoint News Feed
N
News and Events Feed by Topic
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
F
Full Disclosure
T
Troy Hunt's Blog
D
Darknet – Hacking Tools, Hacker News & Cyber Security
Project Zero
Project Zero
P
Palo Alto Networks Blog
Recorded Future
Recorded Future
美团技术团队
D
Docker
PCI Perspectives
PCI Perspectives
Microsoft Azure Blog
Microsoft Azure Blog
MongoDB | Blog
MongoDB | Blog
L
LINUX DO - 最新话题
Recent Announcements
Recent Announcements
Hacker News: Ask HN
Hacker News: Ask HN
人人都是产品经理
人人都是产品经理
月光博客
月光博客
D
DataBreaches.Net
The Hacker News
The Hacker News
爱范儿
爱范儿
V
Visual Studio Blog
Engineering at Meta
Engineering at Meta
SecWiki News
SecWiki News
cs.CV updates on arXiv.org
cs.CV updates on arXiv.org
A
About on SuperTechFans
Latest news
Latest news
GbyAI
GbyAI
T
Tor Project blog
L
LINUX DO - 热门话题
Security Latest
Security Latest
博客园 - 聂微东
Y
Y Combinator Blog
AI
AI
M
MIT News - Artificial intelligence

Aesrium の树洞

CS233A 学习笔记 2024 年下半年总结 2023 年年末总结 CD26 游记 2022 年年末总结 记第一次网站备案 2022 年网课日记 浅谈 WOTA 艺 2021 年年末总结 我的这三年 简单谈谈我对这次《明日方舟》夏活的看法 我吹爆羽毛笔! 我的 OI 回忆录 PyQt5 学习笔记 为什么我最终放弃了中考 开始使用 VPS 了! WC2021 游记 再见 2020,你好 2021 【CodeForces 431E】 Chemistry Experiment
【CodeForces 243A】 The Brand New Function
Aesrium · 2021-01-12 · via Aesrium の树洞

发表于|更新于|题解

|总字数:601|阅读时长:2分钟|浏览量:|

题目大意

给出一个序列 aa,设 f(l,r)f(l,r) 表示 al∣al+1∣al+2∣⋯∣ara_l|a_{l+1}|a_{l+2}|\cdots|a_r,求 f(l,r)f(l,r) 有多少不同的值。

思路

显然,对于任意 llf(l,r)≤f(l,r+1)f(l,r)\le f(l,r+1),也就是说,对于从同一个数开始的所有区间,它们的值一定是随长度增加而增加的,所以,我们假设有一个变量 tt,它从 ala_l 开始不停地与下一个数相或,这个 tt 的值增加的次数就是所有以 ala_l 为左端点的区间中不同的 f(l,r)f(l,r) 的值的数量,因为 tt 只会增大,不会变小。

那么我们怎么知道这个 tt 变大了多少次呢?考虑 tt 在什么情况下会变大,显然,tt 会变大,当且仅当原来 tt00 的位变成了 11,而且每一位最多会变一次,所以,我们维护一个 nxtnxt 数组,用 nxti,jnxt_{i,j} 表示 aia_iana_n 这些数中第 jj 位为 11 的第一个数的下标,由于有些位可能同时变成 11,所以我们还需要对下标进行去重。

最终时间复杂度 O(nlog⁡M)O(n\log M),常数稍大。

参考代码

对于 nxtnxt 数组,这里采用的是滚动数组的方法,减小了一点空间复杂度。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 1e5+10;
struct QwQ
{
int val;
int id;
bool operator < (const QwQ &a) const
{
return val == a.val ? id < a.id : val < a.val;
}
};
QwQ t[30];
int n, mx, a[N], b[N*15], nxt[30];
ll ans;
int main()
{
scanf("%d", &n);
for(int i = 1; i <= n; i++)
scanf("%d", &a[i]);
for(int i = n; i >= 1; i--)
{
int x = a[i];
for(int j = 0; j <= 20; j++)
{
t[j] = (QwQ){nxt[j], j};
if((a[i]>>j)&1)
nxt[j] = i;
}
sort(t, t+21);
for(int j = 0; j <= 20; j++)
if(t[j].val)
{
if(!b[x] && (j == 0 || t[j].val != t[j-1].val))
{
ans++;
b[x] = 1;
}
x |= (1<<t[j].id);
}
if(!b[x])
{
ans++;
b[x] = 1;
}
}
printf("%lld", ans);
return 0;
}