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

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. App遍历探讨(含源代码)

    好像好久没有更新博客了,之前写的几篇博客关于自动化的框架的居多,其中好多博友向我提了好多问题,我没有回复.这里给博友道个歉~ ~ 总结几点原因如下: 1.我一般很少上博客,看到了都是好几天之前的问题 ...

  2. 7年,OpenStack从入门到放弃|送书

    七年之痒这个词,大家经常说,不过起源,估计就不是谁都清楚.这是梦露的一部影片的名字,后来大家发现无论是企业,家庭,甚至政府,都在第七年时间段上面临各种麻烦. OpenStack存在的问题,其实已经不是 ...

  3. 为什么Fourier分析?

    本文旨在给出Fourier分析的几个动机. 目录 波动方程 热导方程 Lapalce变换 求和公式 表示论 特征理论 参考资料 波动方程 考虑一维的波动方程最简单的边值问题$$u(x,t), x\in ...

  4. 07-JavaScript之常用内置对象

    JavaScript之常用内置对象 1.数组Array 1.1数组的创建方式 // 直接创建数组 var colors = ['red', 'blue', 'green']; console.log( ...

  5. 家庭记账本小程序之框架设计(java web基础版一)

    1.设计主页 main.jsp <%@ page language="java" contentType="text/html; charset=UTF-8&quo ...

  6. 【学习总结】GirlsInAI ML-diary day-9-dict字典

    [学习总结]GirlsInAI ML-diary 总 原博github链接-day9 认识dict字典 新的数据类型dict. dict全称dictionary,在其他语言中也称为map,使用键-值( ...

  7. 6-4 The present perfect

    1 Summary The present perfect is an important verb tense in English. It is used to talk about things ...

  8. Linux operating system basic knowleadge

    1.Linux目录系统结构  It makes sense to explore the Linux filesystem from a terminal window. In fact, that ...

  9. Django初印象之视图(view)

    一.view的初印象 一个视图函数(类),简称视图.我们发起web请求时,返回的web响应.[大家约定成俗将视图放置在项目(project)或应用程序(app)目录中的名为views.py的文件中.] ...

  10. UVA 10618 Tango Tango Insurrection

    https://vjudge.net/problem/UVA-10618 题目 你想学着玩跳舞机.跳舞机的踏板上有4个箭头:上.下.左.右.当舞曲开始时,屏幕上会有一些箭头往上移动.当向上移动箭头与顶 ...