出现了一篇跑得炒鸡慢的题解!

noteskey

无 fuck 说,好像就是整个数列分块然后合并区间...什么的吧

对于每块内部就是算一下前缀信息、后缀信息(就是以 第一个点/最后一个点 为一个边界,不超过 log 个不同的 or 值所要到达的最 左/右 点)和中值信息(就是某种区间长度内能 or 出来的最大值)

然后询问的时候从第一个块开始,向后先查询当前块与下一个块合并的答案,然后更新当前块

watch out

nothing ,打代码的时候注意细节貌似是所有 coding 的 gift ? 【雾

code

//by Judge
#pragma GCC optimize(3)
#pragma GCC optimize("unroll-loops")
#include<bits/stdc++.h>
#define Rg register
#define fp(i,a,b) for(Rg int i=(a),I=(b)+1;i<I;++i)
#define fd(i,a,b) for(Rg int i=(a),I=(b)-1;i>I;--i)
#define P pair<int,int>
#define ll long long
#define se second
#define fi first
using namespace std;
const int bl=403;
const int M=6e4+3;
typedef int arr[M];
#ifndef Judge
#define getchar() (p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++)
#endif
char buf[1<<21],*p1=buf,*p2=buf;
bool operator <(P& a,P& b){return a.fi^b.fi?a.fi<b.fi:a.se>b.se;}
inline bool cmax(int& a,int b){return a<b?a=b,1:0;}
inline bool cmin(int& a,int b){return a>b?a=b,1:0;}
inline int read(){ int x=0,f=1; char c=getchar();
for(;!isdigit(c);c=getchar()) if(c=='-') f=-1;
for(;isdigit(c);c=getchar()) x=x*10+c-'0'; return x*f;
} char sr[1<<21],z[20];int CCF=-1,Z;
inline void Ot(){fwrite(sr,1,CCF+1,stdout),CCF=-1;}
inline void print(int x,char chr='\n'){
if(CCF>1<<20)Ot();if(x<0)sr[++CCF]=45,x=-x;
while(z[++Z]=x%10+48,x/=10);
while(sr[++CCF]=z[Z],--Z);sr[++CCF]=chr;
} int n,m,K,ans,pv,a[M],pos[M];
P q[M],vec[bl+3],c[bl+3];
struct BLK{ int mx[bl+3],val[bl+3],L,R,cntp,cnts,all; P pre[33],suf[33]; //最多 log 个不同的 or 值
// mx[i] 长为 i 的区间 or 和的 max 值,val 表示块内每个点的值
inline void re(){ memset(mx,0,sizeof mx); int p; // 就算 mx 数组
p=cntp=0; fp(i,1,bl) if((p|=val[i])!=pre[cntp].fi) pre[++cntp]=P(p,i+L-1);
p=cnts=0; fd(i,bl,1) if((p|=val[i])!=suf[cnts].fi) suf[++cnts]=P(p,i+L-1);
int head=1,tail=0;
fd(i,bl,1){ int lst=tail,v=val[i];
for(Rg int j=v;j;j^=j&-j) q[++tail]=P(__builtin_ctz(j),i);
fp(j,head,lst) if(!(v>>q[j].fi&1)) q[++tail]=q[j]; head=lst+1;
Rg int now=0,pos; fp(j,head,tail)
pos=q[j].se,cmax(mx[pos-i+1],now|=val[pos]);
}
fp(i,2,bl) cmax(mx[i],mx[i-1]); all=pre[cntp].fi;
}
inline void build(int l,int r){ L=l,R=r;
fp(i,l,r) val[i-l+1]=a[i]; re();
}
inline void update(int pos,int v){val[pos-L+1]=v,re();} //重构块
inline int len(int v){return lower_bound(mx+1,mx+1+bl,v)-mx;}
//得到构成长度为 v 的 or 和区间最短长度
inline void merge(){ int l=1,r=1,it=0; //将当前的区间和 vec 后缀合并
while(l<=pv&&r<=cnts) c[++it]=vec[l]<suf[r]?vec[l++]:suf[r++];
while(l<=pv) c[++it]=vec[l++]; while(r<=cnts) c[++it]=suf[r++];
vec[1]=c[1]; fp(i,2,it) vec[i]=c[i],
vec[i].fi==vec[i-1].fi&&(vec[i].se=vec[i-1].se);
pv=unique(vec+1,vec+1+it)-1-vec;
}
inline void check(int v){ int len=2e9; //用后缀 vec 和当前块的前缀更新答案
fp(i,1,cntp) while(pv&&(vec[pv].fi|pre[i].fi)>=v)
cmin(len,pre[i].se-vec[pv--].se+1); cmin(ans,len);
}
}b[131];
int main(){ n=read(),m=read(); fp(i,1,n) a[i]=read();
fp(i,1,n) pos[i]=(i-1)/bl+1; K=pos[n],n=K*bl;
fp(i,1,K) b[i].build((i-1)*bl+1,i*bl);
while(m--){
if(read()&1){ int x=read(),y=read();
b[pos[x]].update(x,y),a[x]=y;
} else{ ans=2e9; int x=read();
fp(i,1,K) if(b[i].all>=x)
cmin(ans,b[i].len(x));
pv=0,b[1].merge();
fp(i,2,K){
b[i].check(x);
fp(j,1,pv) vec[j].first|=b[i].all;
b[i].merge();
} print(ans<2e9?ans:-1);
}
} return Ot(),0;
}

题解 P5065 【[Ynoi2014]不归之人与望眼欲穿的人们】的更多相关文章

  1. [Ynoi2014]不归之人与望眼欲穿的人们

    题目大意: 给定一个序列,每次单点修改一个数,或给定$x$,询问最短的or起来大于等于$x$的区间的长度(不存在输出-1). 解题思路: 在太阳西斜的这个世界里,置身天上之森.等这场战争结束之后,不归 ...

  2. 【题解】BZOJ 3600: 没有人的算术——替罪羊树、线段树

    题目传送门 题意 具体的自己去上面看吧...反正不是权限题. 简单来说,就是定义了一类新的数,每个数是0或者为 \((x_L, x_R)\) ,同时定义比较大小的方式为:非零数大于零,否则按字典序比较 ...

  3. [Ynoi2015]即便看不到未来

    题目大意: 给定一个序列,每次询问,给出一个区间$[l,r]$. 设将区间内的元素去重后重排的数组为$p$,求$p$中长度为$1\sim 10$的极长值域连续段个数. 长度为$L$的极长值域连续段的定 ...

  4. [Ynoi2015]纵使日薄西山

    题目大意: 给定一个序列,每次单点修改,然后进行询问. 定义一次操作为,选择一个位置$x$,将这个位置的数和左边.右边两个位置的数(不存在则忽略)各减去1,然后和0取max. 对序列中最大的位置进行一 ...

  5. [Ynoi2015]盼君勿忘

    题目大意: 给定一个序列,每次查询一个区间\([l,r]\)中所有子序列分别去重后的和\(\bmod p\)(每次询问模数不同). 解题思路: 在太阳西斜的这个世界里,置身天上之森.等这场战争结束之后 ...

  6. [Ynoi2015]我回来了

    题目大意: 给定一张无向无权图,每次给定若干个二元组\((x_i,y_i)\),定义点\(u\)满足条件,当且仅当存在\(i\),并满足\(dist(u,x_i)\leqslant y_i\)(\(d ...

  7. [Ynoi2015]此时此刻的光辉

    题目大意: 给定一个序列,每次询问一段区间的数的乘积的约数个数. 解题思路: 在太阳西斜的这个世界里,置身天上之森.等这场战争结束之后,不归之人与望眼欲穿的众人, 人人本着正义之名,长存不灭的过去.逐 ...

  8. 题解-AtCoder Code-Festival2017 Final-J Tree MST

    Problem \(\mathrm{Code~Festival~2017~Final~J}\) 题意概要:一棵 \(n\) 个节点有点权边权的树.构建一张完全图,对于任意一对点 \((x,y)\),连 ...

  9. HNOI2018简要题解

    HNOI2018简要题解 D1T1 寻宝游戏 题意 某大学每年都会有一次 Mystery Hunt 的活动,玩家需要根据设置的线索解谜,找到宝藏的位置,前一年获胜的队伍可以获得这一年出题的机会. 作为 ...

随机推荐

  1. Linux内存管理 (9)mmap(补充)

    之前写过一篇简单的介绍mmap()/munmap()的文章<Linux内存管理 (9)mmap>,比较单薄,这里详细的梳理一下. 从常用的使用者角度介绍两个函数的使用:然后重点是分析内核的 ...

  2. vue 2.0 + ElementUI构建树形表格

    解决: 本来想在网上博客找一找解决方法,奈何百度到的结果都不尽人意,思维逻辑不清,步骤复杂,代码混乱,找了半天也没找到一个满意的,所以干脆就自己动手写一个 思路: table需要的数据是array,所 ...

  3. SpringCloud(1)服务注册与发现Eureka

    1.创建1个空白的工程 2.创建2个model工程 一个module(即SpringBoot)工程作为服务注册中心,即Eureka Server,另一个作为Eureka Client. Eureka ...

  4. ABP大型项目实战(2) - 调试与排错 - 日志 - 查看审计日志

    这是<ABP大型项目实战>系列文章的一篇.   项目发布到生产环境后难免会有错误. 那么如何进行调试和排错呢?   我看到俱乐部里有人是直接登陆生产服务器把数据库下载到开发机器进行调试排错 ...

  5. JS 函数节流与防抖

    前言 事件的触发权很多时候属于用户,可能会出现下列问题: 向后台发送数据,用户频繁触发,对服务器造成压力: 一些浏览器事件,如window.onresize,window.mousemove等,触发的 ...

  6. linux安装tomcat部署web项目

    我用的是如下图的两个软件,连接linux服务器. 其中WinSCp是传输文件用的,SecureCRT是用来输入命令的. 1.复制tomcat到指定目录(可复制到你想要的目录下),命令如下: cp /路 ...

  7. (转)JMeter学习逻辑控制器

    JMeter中的Logic Controller用于为Test Plan中的节点添加逻辑控制器. JMeter中的Logic Controller分为两类:一类用来控制Test Plan执行过程中节点 ...

  8. nginx代理部署Vue与React项目

    nginx代理部署Vue与React项目 一,介绍与需求 1.1,介绍 Nginx (engine x) 是一个高性能的HTTP和反向代理服务,也是一个IMAP/POP3/SMTP服务.Nginx是由 ...

  9. js DOM操作 容易犯的错误

    这样一段html片段 <select class="form-control" id="course_chapter" onchange="fi ...

  10. [SimplePlayer] 1. 从视频文件中提取图像

    在开始之前,我们需要了解视频文件的格式.视频文件的格式众多,无法三言两语就能详细分析其结构,尽管如此,ffmpeg却很好地提取了各类视频文件的共同特性,并对其进行了抽象描述. 视频文件格式,统称为co ...