传送门

神仙题! 听@Yubai给我讲了半个下午,快%@Yubai

  • 见到这些奇奇怪怪的题是不是应该试着证下状态数上界啊

首先观察题目里给的柿子,可以发现 \(or-and\) 单调增, \(min-max\) 单调减

神仙思路,发现对于一个给定的端点,我怀疑出题人是左撇子,不同的 \(or-and\) 最多只有 \(2logn\) 个,证明应该很简单

那尝试把这些 \(or-and\) 相同的区间拎出来,从右向左枚举区间,在区间内二分可得合法的最远右端点

然后问题来了:如何 \(O(1)\) 维护出这些区间

神仙思路,考虑什么是这些区间的边界,会发现一个数是边界当且仅当这一位上出现了之前没有在这一位上出现过的数

也即比如左边界上第 \(i\) 位是1,那向右找到第一个这一位上是0的数,那个数就会是一个边界

这个可以维护出一个next0和一个next1单调指针,每次排个序处理

然后区间最值,区间与或都需要 \(O(1)\) 出,都可以用ST表

  • 所以满足区间可重性的东西都可以用ST表?

  • 关于区间整体取max:

    另一种实现方法是把线段差分,拆分为在 \(l\) 插入一个长度,在 \(r\) 删除一个长度的事件,拿一个multiset维护,每次取出最大值即可

    但这样要求区间数不能太多

  • 关于ST表和lca的fa数组:

    把大小是log的那一维放在前面真的会快

然后具体实现上注意我让每个端点是区间的右端点,所以每次还得特别把位置 \(n\) 扔进去

Code:

#include <bits/stdc++.h>
using namespace std;
#define INF 0x3f3f3f3f
#define N 1000010
#define ll long long
#define reg register int
#define fir first
#define sec second
#define make make_pair
#define max2(a, b) ((a)>(b)?(a):(b))
#define min2(a, b) ((a)<(b)?(a):(b))
//#define int long long char buf[1<<21], *p1=buf, *p2=buf;
#define getchar() (p1==p2&&(p2=(p1=buf)+fread(buf, 1, 1<<21, stdin)), p1==p2?EOF:*p1++)
inline int read() {
int ans=0; char c=getchar();
while (!isdigit(c)) c=getchar();
while (isdigit(c)) {ans=(ans<<3)+(ans<<1)+(c^48); c=getchar();}
return ans;
} int n, k;
int ta1[28][N], ta2[28][N], ta3[28][N], ta4[28][N], top, lg[N], a[N];
pair<int, int> add[N], del[N];
multiset<int> s;
struct point{
int dlt, pos0, pos1;
point():pos0(1),pos1(1){}
int nxt0(int i) {
//cout<<"nxt0: "<<i<<' '<<pos0<<endl;
if (i>=pos0) {pos0=i+1; i=1<<dlt; while (pos0<=n && (a[pos0]&i)) ++pos0;}
//cout<<"return "<<pos0<<endl;
return pos0;
}
int nxt1(int i) {
if (i>=pos1) {pos1=i+1; i=1<<dlt; while (pos1<=n && !(a[pos1]&i)) ++pos1;}
return pos1;
}
}p[28];
inline int qmin(int l, int r) {
int t=lg[r-l+1]-1;
return min(ta2[t][l], ta2[t][r-(1<<t)+1]);
}
inline int qmax(int l, int r) {
int t=lg[r-l+1]-1;
return max(ta1[t][l], ta1[t][r-(1<<t)+1]);
}
inline int qor(int l, int r) {
int t=lg[r-l+1]-1;
return ta3[t][l]|ta3[t][r-(1<<t)+1];
}
inline int qand(int l, int r) {
int t=lg[r-l+1]-1;
return ta4[t][l]&ta4[t][r-(1<<t)+1];
} signed main()
{
n=read(); k=read();
for (reg i=1; i<=n; ++i) a[i]=read();
for (reg i=1; i<=n; ++i) ta1[0][i]=ta2[0][i]=ta3[0][i]=ta4[0][i]=a[i];
for (reg i=1; i<=n; ++i) lg[i]=lg[i-1]+(1<<lg[i-1]==i);
int lim=lg[n]-1;
for (reg j=0; j<lim; ++j)
for (reg i=1,t,lm=n-(1<<(j+1))+1; i<=lm; ++i) {
t=i+(1<<j);
ta1[j+1][i]=max2(ta1[j][i], ta1[j][t]);
ta2[j+1][i]=min2(ta2[j][i], ta2[j][t]);
ta3[j+1][i]=ta3[j][i]|ta3[j][t];
ta4[j+1][i]=ta4[j][i]&ta4[j][t];
}
for (reg i=0; i<27; ++i) p[i].dlt=i;
int tem[30];
for (reg i=1; i<=n; ++i) {
//cout<<"i="<<i<<": "<<endl;
for (reg j=0; j<27; ++j) tem[j]=(a[i]&(1<<j))?p[j].nxt0(i):p[j].nxt1(i);
tem[27]=i; tem[28]=n+1;
sort(tem, tem+29);
//assert(tem[0]==i);
//cout<<"tem: "; for (int i=0; i<=27; ++i) cout<<tem[i]<<' '; cout<<endl;
for (reg j=28,t1,t2,l,r,mid; j; --j) {
if (tem[j-1]==tem[j]) continue;
t1=qor(i, tem[j]-1)-qand(i, tem[j]-1), t2=qmin(i, tem[j-1])-qmax(i, tem[j-1]);
if (t1+t2>=k) {
//cout<<"t1="<<t1<<" and t2="<<t2<<' '<<t1+t2<<endl;
//cout<<"tem_j: "<<tem[j-1]<<' '<<tem[j]-1<<endl;
l=tem[j-1], r=tem[j]-1;
while (l<=r) {
mid=(l+r)>>1;
if (t1+qmin(i, mid)-qmax(i, mid)>=k) l=mid+1;
else r=mid-1;
}
//cout<<"lr: "<<l<<' '<<r<<endl;
add[++top]=make(i, l-i), del[top]=make(l, l-i);
break;
}
}
}
sort(del+1, del+top+1);
int pos1=1, pos2=1;
//cout<<"---add---"<<endl; for (int i=1; i<=top; ++i) cout<<add[i].fir<<','<<add[i].sec<<endl;
//cout<<"---del---"<<endl; for (int i=1; i<=top; ++i) cout<<del[i].fir<<','<<del[i].sec<<endl;
for (reg i=1; i<=n; ++i) {
//cout<<"add: "<<add[i].sec<<endl;
while (pos1<=top && add[pos1].fir<=i) s.insert(add[pos1++].sec);
while (pos2<=top && del[pos2].fir<=i) {
//cout<<"del: "<<del[pos].fir<<' '<<del[pos].sec<<endl;
s.erase(s.find(del[pos2++].sec));
}
printf("%d ", s.size()?*s.rbegin():-1);
}
printf("\n"); return 0;
}

题解 Cicada 拿衣服的更多相关文章

  1. 「10.28」Dove 打扑克(链表)·Cicada 与排序(概率)·Cicada 拿衣服(各种数据结构)

    A. Dove 打扑克 考场思考半天线段树树状数组,没有什么想法 打完暴力后突然想到此题用链表实现会很快. 因为只有$n$堆,所以设最多有$x$个不同的堆数,那么$x\times (x-1)/2==n ...

  2. [CSP-S模拟测试]:Cicada拿衣服(暴力+乱搞)

    题目传送门(内部题94) 输入格式 第一行两个整数$n,k$,代表衣服的数量和阈值. 接下来一行$n$个数,第$i$个数$a_i$表示每件衣服的愉悦值. 输出格式 输出一行$n$个数,第$i$个数为$ ...

  3. NOIP 模拟 $36\; \rm Cicada 拿衣服$

    题解 \(by\;zj\varphi\) 发现右端点固定时,左端点的 \(min-max\) 单调递减,且对于 \(or\) 和 \(and\) 相减,最多有 \(\rm2logn\)个不同的值,且相 ...

  4. 20210811 Dove 打扑克,Cicada 与排序,Cicada 拿衣服

    考场 开考感觉 T3 比较可做.T1 看上去不难但毫无思路. 先想了 25min T3,想到一个确定左端点,二分最长的右端点,甚至想到了用猫树维护区间 or and...上厕所回来发现假了,没有单调性 ...

  5. [考试反思]1028csp-s模拟测试91:预估

    这一轮是要闹哪样啊???前十都死活进不去??? 能不能不要到联赛前突然连续掉链子啊!!! 总算难得的切掉了T1.然后又一次把T2和T3的难度估反了 结果给T2剩下了30分钟,想到正解来不及打了. 然后 ...

  6. Noip模拟36 2021.8.11

    刚题的习惯还是改不了,怎么办??? T1 Dove打扑克 考场上打的动态开点线段树+并查集,考后发现自己像一个傻子,并查集就行.. 这几天恶补数据结构疯了 用树状数组维护后缀和,$siz_i$表示编号 ...

  7. csp-s模拟测试91

    csp-s模拟测试91 倒悬吃屎的一套题. $T1$认真(?)分析题意发现复杂度不能带$n$(?),计划直接维护答案,考虑操作对答案的影响,未果.突然发现可以动态开点权值线段树打部分分,后来$Tm$一 ...

  8. noip模拟36

    \(\color{white}{\mathbb{荷花映日,莲叶遮天,名之以:残荷}}\) 今天再次翻车掉出前十 开题看错 \(t1\) 以为操作2的值固定发现是个简单题,然后 \(t2\) 开始大力 ...

  9. 2021.8.11考试总结[NOIP模拟36]

    T1 Dove玩扑克 考场并查集加树状数组加桶期望$65pts$实际$80pts$,考后多开个数组记哪些数出现过,只扫出现过的数就切了.用$set$维护可以把被删没的数去掉,更快. $code:$ 1 ...

随机推荐

  1. 一道内部ctf文件包含题

    拿到题目 在burp里看下 拿到源码 很明显是一道文件包含题目,包含cookie里的值,于是构造Cookie:language=chinese试试   文件变成中文的了,说明中文语言进行了包含并替换 ...

  2. 【Azure Redis 缓存】云服务Worker Role中调用StackExchange.Redis,遇见莫名异常(RedisConnectionException: UnableToConnect on xxx 或 No connection is available to service this operation: xxx)

    问题描述 在Visual Studio 2019中,通过Cloud Service模板创建了一个Worker Role的角色,在角色中使用StackExchange.Redis来连接Redis.遇见了 ...

  3. 前端开发入门到进阶第三集【js高度计算公式】

    <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/stri ...

  4. Python多线程爬取某网站表情包

    # 爬取网络图片import requestsfrom lxml import etreefrom urllib import requestfrom queue import Queue # 导入队 ...

  5. springboot-3-web开发

    一.视图层技术thymeleaf 我们一般都是基于3.x版本 1.流程: 导入依赖 <!--整合thymeleaf技术--> <dependency> <groupId& ...

  6. Debian9 无线网卡驱动安装

    https://wiki.debian.org/iwlwifi sudo vi /etc/apt/sources.list --------- ..... deb http://httpredir.d ...

  7. Linux虚拟机与主机网络连接配置与文件传输

    网络配置 对于VMware虚拟机 1. 设置linux系统的网络配置,如下(NAT为默认配置,这里采用这一配置) 2. 主机中配置本地连接-属性-共享-勾选红框配置项,如下:     3.重启虚拟机. ...

  8. [考试总结]noip18

    发现之前咕掉了这个考试的总结. 今天就把它给补上. 这也是一个炸裂的一场 开局以为 \(T1\) 可做,然而事实证明我又错了... 莽了一个随机化上去,轻松过了所有样例... 以为稳了 然而挂掉了.. ...

  9. JavaScript关于对象的一些小知识

    javascript的对象 javascriot(之后用js代替)中基本数据类型之一,是复合类型的数据. 对象在js中应用十分广泛,几乎所有的的事物都是做对象,js的对象拥有自己的属性和方法的数据 在 ...

  10. 复杂多变场景下的Groovy脚本引擎实战

    一.前言 因为之前在项目中使用了Groovy对业务能力进行一些扩展,效果比较好,所以简单记录分享一下,这里你可以了解: 为什么选用Groovy作为脚本引擎 了解Groovy的基本原理和Java如何集成 ...