传送门

神仙题! 听@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. 使用Hugo框架搭建博客的过程 - 前期准备

    前言 这篇教程介绍了如何搭建这样效果的博客. 所需步骤 可以从这样的角度出发: 注册域名. 使用CDN加快网站访问速度. 网站内容需要部署在服务器或对象存储平台上. 重要的是放什么内容.博客需要选择框 ...

  2. (学习心路历程)Vue过渡/动画 VS. 过渡/动画

    [此篇为本人的个人见解和哔哔赖赖,如果有观点不对的地方,还请大家指出来哇!!] 最近实习在做一个项目,里面应用的动画效果还蛮复杂的,因为本身对Vue框架比较熟悉,所以最终选择了Vue框架. 自己之前从 ...

  3. Linux之19——Shell编程基础详解

    第一部分:Linux Shell 简介 Shell 是一个用 C 语言编写的程序,它是用户使用 Linux 的桥梁.Shell 既是一种命令语言,又是一种程序设计语言. Shell 是指一种应用程序, ...

  4. C语言:特殊点

    编译器给变量分配内存在函数外部定义的变量叫做全局变量(Global Variable),在函数内部定义的变量叫做局部变量(Local Variable)一个变量,即使不给它赋值,它也会有一个默认的值, ...

  5. 使用python对工作簿每个sheet表进行数据可视化展示(本案例是从第2个sheet开始循环读取也就是索引为1的表)

    # 导入相关模块from pyecharts.charts import Barfrom pyecharts import options as optsfrom pyecharts.charts i ...

  6. 【记录】如何造一个vite插件(2)

    上一篇已经把vite插件的基础结构搭建起来了,这一次就来聊聊继续完善开发环境. 完善开发环境 生成d.ts文件 先来修改一下lib/index.ts这个文件 export interface user ...

  7. ajax和springmvc的请求响应原理——深入理解jQuery中$.get、$.post、$.getJSON和$.ajax的用法

    1,四大重要部分: 请求链接 post请求和get请求 请求参数形式 响应内容形式 2,从springmvc的controller角度,controller能接收到请求的前提 请求链接必须对应 pos ...

  8. ubuntu平台下,字符集的转换命令iconv

    iconv命令格式 iconv -f 源字符集(要转换文件的字符集) -t 目标字符集  file iconv -f gb18030 -t utf-8 file 默认情况下,不改变原文件,输出到屏幕. ...

  9. nacos Connection refused (Connection refused)

    记录一次"异常bug",具体信息如下.主要是记录一下处理过程,可能口水话比较多,如果想看结果,直接往后拉即可. 最后一行 起初,运维同事找到我,跟我说程序出问题了,系统升级,一直连 ...

  10. 网络损伤仪WANsim的功能与型号

    网络损伤仪简介 WANsim网络损伤仪是一款可以模拟真实的广域网状况的设备.它可以通过简单的数据填写模拟出时延.带宽抖动.丢包.乱序.误码.报文重复等网络状况. 大多数公司在进行产品测试时,只关注了应 ...