题解 P5065 【[Ynoi2014]不归之人与望眼欲穿的人们】
出现了一篇跑得炒鸡慢的题解!
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]不归之人与望眼欲穿的人们】的更多相关文章
- [Ynoi2014]不归之人与望眼欲穿的人们
题目大意: 给定一个序列,每次单点修改一个数,或给定$x$,询问最短的or起来大于等于$x$的区间的长度(不存在输出-1). 解题思路: 在太阳西斜的这个世界里,置身天上之森.等这场战争结束之后,不归 ...
- 【题解】BZOJ 3600: 没有人的算术——替罪羊树、线段树
题目传送门 题意 具体的自己去上面看吧...反正不是权限题. 简单来说,就是定义了一类新的数,每个数是0或者为 \((x_L, x_R)\) ,同时定义比较大小的方式为:非零数大于零,否则按字典序比较 ...
- [Ynoi2015]即便看不到未来
题目大意: 给定一个序列,每次询问,给出一个区间$[l,r]$. 设将区间内的元素去重后重排的数组为$p$,求$p$中长度为$1\sim 10$的极长值域连续段个数. 长度为$L$的极长值域连续段的定 ...
- [Ynoi2015]纵使日薄西山
题目大意: 给定一个序列,每次单点修改,然后进行询问. 定义一次操作为,选择一个位置$x$,将这个位置的数和左边.右边两个位置的数(不存在则忽略)各减去1,然后和0取max. 对序列中最大的位置进行一 ...
- [Ynoi2015]盼君勿忘
题目大意: 给定一个序列,每次查询一个区间\([l,r]\)中所有子序列分别去重后的和\(\bmod p\)(每次询问模数不同). 解题思路: 在太阳西斜的这个世界里,置身天上之森.等这场战争结束之后 ...
- [Ynoi2015]我回来了
题目大意: 给定一张无向无权图,每次给定若干个二元组\((x_i,y_i)\),定义点\(u\)满足条件,当且仅当存在\(i\),并满足\(dist(u,x_i)\leqslant y_i\)(\(d ...
- [Ynoi2015]此时此刻的光辉
题目大意: 给定一个序列,每次询问一段区间的数的乘积的约数个数. 解题思路: 在太阳西斜的这个世界里,置身天上之森.等这场战争结束之后,不归之人与望眼欲穿的众人, 人人本着正义之名,长存不灭的过去.逐 ...
- 题解-AtCoder Code-Festival2017 Final-J Tree MST
Problem \(\mathrm{Code~Festival~2017~Final~J}\) 题意概要:一棵 \(n\) 个节点有点权边权的树.构建一张完全图,对于任意一对点 \((x,y)\),连 ...
- HNOI2018简要题解
HNOI2018简要题解 D1T1 寻宝游戏 题意 某大学每年都会有一次 Mystery Hunt 的活动,玩家需要根据设置的线索解谜,找到宝藏的位置,前一年获胜的队伍可以获得这一年出题的机会. 作为 ...
随机推荐
- 4-STM32物联网开发WIFI(ESP8266)+GPRS(Air202)系统方案安全篇(为域名申请SSl证书)
3-STM32物联网开发WIFI(ESP8266)+GPRS(Air202)系统方案安全篇(购买域名,域名绑定IP) 然后就是等着..... 假设可以了 咱呢是配置MQTT实现SSL安全加密通信,所以 ...
- 人撒娇地撒基督教扫ID祭扫我京东is啊单间
下下卷惜西,清首花我下望心如单水.低如见惜折 卷水满门我,如二折莲开低下悠子鸦.南水水暮洲 凄暮红过在,莫处言树鸿怀莲绿门莲.杆鸿中花海 见门塘采心,何西杏知底底梅即色花.红两霜言海 秋飞曲杆明,花南 ...
- Neutron :默认通过 dnsmasq 实现 DHCP 功能----Namespace
Neutron 提供 DHCP 服务的组件是 DHCP agent. DHCP agent 在网络节点运行上,默认通过 dnsmasq 实现 DHCP 功能. 配置 DHCP agent DHCP ...
- 利用Python中SocketServer 实现客户端与服务器间非阻塞通信
利用SocketServer模块来实现网络客户端与服务器并发连接非阻塞通信 版权声明 本文转自:http://blog.csdn.net/cnmilan/article/details/9664823 ...
- monkey事件简介
操作事件简介 Monkey所执行的随机事件流中包含11大事件,分别是触摸事件.手势事件.二指缩放事件.轨迹事件.屏幕旋转事件.基本导航事件.主要导航事件.系统按键事件.启动Activity事件.键盘事 ...
- Siamese network 孪生神经网络
Siamese network 孪生神经网络 https://zhuanlan.zhihu.com/p/35040994 https://blog.csdn.net/shenziheng1/artic ...
- Qt如何去掉按钮等控件的虚线框(焦点框)
方法1:可以通过代码ui->pushButton->setFocusPolicy(Qt::NoFocus)或在Qt Creator的属性列表中设置. 方法2:如果在嵌入式设备中需要通过按键 ...
- python学习日记(OOP——静态方法和类方法)
classmethod 类方法在Python中使用比较少,类方法传入的第一个参数为cls,是类本身.并且,类方法可以通过类直接调用,或通过实例直接调用.但无论哪种调用方式,最左侧传入的参数一定是类本身 ...
- 动态dp学习笔记
我们经常会遇到一些问题,是一些dp的模型,但是加上了什么待修改强制在线之类的,十分毒瘤,如果能有一个模式化的东西解决这类问题就会非常好. 给定一棵n个点的树,点带点权. 有m次操作,每次操作给定x,y ...
- python之路day03--数据类型分析,转换,索引切片,str常用操作方法
数据类型整体分析 int :用于计算bool:True False 用户判断str:少量数据的存储 list:列表 储存大量数据 上亿数据[1,2,3,'zzy',[aa]] 元组:只读列表(1,23 ...