P5065 [Ynoi2014] 不归之人与望眼欲穿的人们
被卡常了,大败而归。
注意到是不同寻常的 or 和,不难推出最多经过 \(\log a\) 次变化就顶到值域上限。
单点修改,全局查询,所以要有一个平衡复杂度的东西,因此分块。
块内维护维护 \(f(len)\) 表示长度为 \(len\) 的所有子区间 or 和的最大值并取前缀 max,这样询问就可以直接二分找块内满足条件的最小长度了,设 \(dp_{i, j}\) 为满足 \([dp_{i, j}, i]\) or 和 \(i\) 为 1 的最大的 \(dp_{i, j}\),不难得所有 \([dp_{i, j}, i\) 才是 \(f(len)\) 的有效贡献区间,因此修改时暴力重构整个块和 \(f, dp\),每次做 ST 表即可做到修改 \(O(\sqrt{n}(\log + \log a))\)。
对于跨过块的答案,考虑每个块维护前/后缀 \(\log n\) 次变化的位置,加入新的块的时候,双指针在原后缀和加入块的前缀统计贡献即可。
复杂度 \(O(m\sqrt{n}\log a)\)
Code:
#include <stdio.h>
#include <algorithm>
#include <string.h>
#include <cctype>
#include <vector>
#include <queue>
#include <bitset>
#include <cmath>
#define vi vector<int>
#define pb push_back
#define mp make_pair
#define st first
#define nd second
using namespace std;
typedef long long ll;
typedef pair <int, int> Pii;
const int INF=2147483647;
const int cp=1e9+7;
inline int plust(int x, int y){x+=y;if(x>=cp) x-=cp;if(x<0) x+=cp;return x;}
inline int minut(int x, int y){x-=y;if(x>=cp) x-=cp;if(x<0) x+=cp;return x;}
inline int read(){
char ch=getchar();int x=0, f=1;
while(!isdigit(ch)){if(ch=='-') f=-1; ch=getchar();}
while(isdigit(ch)){x=(x<<3)+(x<<1)+ch-'0';ch=getchar();}
return x*f;
}
inline void write(int x){
if(x<0) putchar('-'), x=-x;
if(x>9) write(x/10);
putchar(x%10+'0');
}
inline int ksm(int a, int b=cp-2){
int ret=1;
for(; b; b>>=1, a=1ll*a*a%cp)
if(b&1) ret=1ll*ret*a%cp;
return ret;
}
const int N=5e4+5;
const int M=1e4+4;
int n, m, B, a[N], bid[N], mxn[M], ors[M], L[M], R[M];
vector <Pii> pre[M], suf[M], pret, suft;
int dp[N][35], ST[N][35], lg[N];
vi mx[M];
int query(int l, int r){int k=lg[r-l+1];return ST[l][k]|ST[r-(1<<k)+1][k];}
void buildst(int l, int r){
for(int i=l; i<=r; ++i) ST[i][0]=a[i];
for(int j=1; j<=lg[r-l+1]; ++j)
for(int i=l; i+(1<<j)-1<=r; ++i)
ST[i][j]=ST[i][j-1]|ST[i+(1<<j-1)][j-1];
}
void rebuild(int idx, int flg){
//整体重构,flg>0 表示 flg 被修改
int l=L[idx], r=R[idx];
// printf("rebuild block %d [%d %d]:%d\n", idx, l, r, flg);
vector <Pii> ().swap(pre[idx]);
vector <Pii> ().swap(suf[idx]);mxn[idx]=ors[idx]=0;
for(int i=r, sf=0, lst=-1; i>=l; mxn[idx]=max(mxn[idx], a[i]), --i, lst=sf)
if((sf|=a[i])^lst) suf[idx].pb(mp(sf, r-i+1));
buildst(l, r);
for(int i=l, pr=0, lst=-1; i<=r; ++i, lst=pr){
mx[idx][i-l+1]=0, ors[idx]|=a[i];
if((pr|=a[i])^lst) pre[idx].pb(mp(pr, i-l+1));
if(pr==INF) break;
for(int j=0; j<=30&&(1ll<<j)<=mxn[idx]; ++j){
if((a[i]>>j)&1) dp[i][j]=i;
else dp[i][j]=dp[i-1][j];
if(dp[i][j]>=l)
mx[idx][i-dp[i][j]+1]=max(mx[idx][i-dp[i][j]+1], query(dp[i][j], i));
}
}
for(int i=1; i<=r-l+1; ++i) mx[idx][i]=max(mx[idx][i-1], mx[idx][i]);
}
int Ef(int idx, int val){
int r=R[idx]-L[idx]+1;if(mx[idx][r]<val) return n+1;
int l=1, ans=r;
while(l<=r){
int mid=l+r>>1;
if(mx[idx][mid]>=val) ans=mid, r=mid-1;
else l=mid+1;
}
return ans;
}
signed main(){
n=read(), m=read();lg[0]=-1;
for(int i=1; i<=n; ++i) a[0]|=(a[i]=read()), lg[i]=lg[i>>1]+1;
for(int i=0; i<=30; ++i) if(a[0]&(1<<i)) B=i;
B=sqrt(n*50);//printf("block len = %d\n", B);
for(int i=1, c=1; i<=n; i+=B){
for(int j=0; j<B&&i+j<=n; ++j) bid[i+j]=c;
L[c]=i, R[c]=min(i+B-1, n);
mx[c].resize(R[c]-L[c]+2, 0);
rebuild(c, 0);++c;
}
for(int i=1; i<=m; ++i){
int op=read();
if(op&1){
int x=read(), y=read();a[x]=y;
rebuild(bid[x], x);
}
else{
int k=read(), sor=0, len=0;int res=n+1;
for(int j=bid[1]; j<=bid[n]; ++j){
if(res==n) break;
res=min(res, Ef(j, k));
// printf("for block %d: find [%d %d]\n", j, v.st, v.nd);
if(j==bid[1])
pret=pre[j], suft=suf[j], sor=ors[j], len=R[j]-L[j]+1;
else{
int sz1=suft.size(), sz2=pre[j].size();
for(int l=sz1-1, r=0; l>=0; --l){
while(r<sz2&&(suft[l].st|pre[j][r].st)<k) ++r;
if(r>=sz2) break;res=min(res, suft[l].nd+pre[j][r].nd);
}
/*合并*/
int lst=-1;
vector <Pii> tmp=pre[j];
for(auto &v:tmp) v.st|=sor, v.nd+=len;
lst=pret.back().st;
for(auto &v:tmp) if(v.st!=lst) pret.pb(v), lst=v.st;
tmp=suf[j];swap(suft, tmp);
for(auto &v:tmp) v.st|=ors[j], v.nd+=R[j]-L[j]+1;
lst=suft.back().st;
for(auto &v:tmp) if(v.st!=lst) suft.pb(v), lst=v.st;
len+=R[j]-L[j]+1, sor|=ors[j];
}
}
if(res<=n) printf("%d\n", res);
else puts("-1");
}
}
return 0;
}
P5065 [Ynoi2014] 不归之人与望眼欲穿的人们的更多相关文章
- [Ynoi2014]不归之人与望眼欲穿的人们
题目大意: 给定一个序列,每次单点修改一个数,或给定$x$,询问最短的or起来大于等于$x$的区间的长度(不存在输出-1). 解题思路: 在太阳西斜的这个世界里,置身天上之森.等这场战争结束之后,不归 ...
- 题解 P5065 【[Ynoi2014]不归之人与望眼欲穿的人们】
出现了一篇跑得炒鸡慢的题解! noteskey 无 fuck 说,好像就是整个数列分块然后合并区间...什么的吧 对于每块内部就是算一下前缀信息.后缀信息(就是以 第一个点/最后一个点 为一个边界,不 ...
- [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]此时此刻的光辉
题目大意: 给定一个序列,每次询问一段区间的数的乘积的约数个数. 解题思路: 在太阳西斜的这个世界里,置身天上之森.等这场战争结束之后,不归之人与望眼欲穿的众人, 人人本着正义之名,长存不灭的过去.逐 ...
- 题解 P5072 【[Ynoi2015] 盼君勿忘】
在太阳西斜的这个世界里,置身天上之森.等这场战争结束之后,不归之人与望眼欲穿的众人, 人人本着正义之名,长存不灭的过去.逐渐消逝的未来.我回来了,纵使日薄西山,即便看不到未来,此时此刻的光辉,盼君勿忘 ...
- 不得不喷一下中控科技,ZKT,恶心的中控,售后技术和屎一样,半年不见人。
要做一个指纹考勤机和后台通信写入到mysql.在淘宝看了好多款,于是决定用指纹考勤机w6.卖家当时说支持二次开发,给我发的sdk.于是买了一台测试.机器来了开始测试,使用发的demo不能使用,于是去中 ...
- GitHub 实现多人协同提交代码并且权限分组管理
转载请标明出处: http://www.cnblogs.com/zhaoyanjun/p/5882784.html 出自[赵彦军博客] 2016-09-19 前言: 在上一篇文章中Android gi ...
随机推荐
- DevOps系列——Jenkins私服
DevOps基础设施较多,所以客官不要太着急,要有个"渐进明细"的过程,前面说了GitLab,这里再说下Jenkins,这俩算 是较为核心的基础组件,其他组件可选项较多,而这俩的地 ...
- 免费在线试用 200+ Linux 和 Unix 操作系统
Linux 和 Unix 存在着各种各样的发行版本,有的界面美观,有的功能强大,想要尝试不同的 Linux 和 Unix 操作系统,你可能会烦于进行本地安装.不急,今天,我们来介绍一个强大的服务,Di ...
- expected at least 1 bean which qualifies as autowire candidate
org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'log ...
- 能详细地讲讲stm32该怎么学吗?
作为一个在嵌入式领域摸爬滚打了好几年的老兵,我想分享一下我学习STM32的心路历程和方法论.坦白说,刚开始接触STM32时,我也是一脸懵逼.机械专业毕业的我转行做嵌入式,第一份工作被调剂到电子部门,实 ...
- 单元测试——Mock RestTemplate
service代码如下: public class TestServiceImpl implements ITestService { @Autowired RestTemplate restTemp ...
- nim 语言实现迭代器
nim语言默认是支持 for x in items 这样的迭代的,而且一个类如果要支持迭代,可以用 yield 关键字,其实在 nim 主页上第二个例子就已经重点介绍了. # Thanks to Ni ...
- MySQL 高可用集群搭建部署
MySQL 高可用集群搭建(GTID 模式 + 自动故障转移) 一.环境规划 角色 IP 地址 说明 主库 (Master) 192.168.1.100 运行 MySQL + Keepalived/M ...
- 一行代码搞定防抖节流:JavaScript新特性解析
防抖(Debounce)和节流(Throttle)是两种前端开发中常用的性能优化技术,尤其在处理高频触发事件如滚动.调整窗口大小.输入等场景中.传统实现这些功能需要编写复杂的函数,但随着JavaScr ...
- 正点原子ALPHA开发板使用4.3寸触摸屏LCD驱动实验显示不正常
显示问题 裸机开发时,驱动教程的PDF里给了4.3寸LCD屏幕的设置参数.如下图所示: 但是按照这个设置,编写设备树dts文件,下载到开发板里,却出现了显示异常,具体来说就是帧率不对,图和字都是歪斜的 ...
- Java Solon v3.3.0 发布(国产优秀应用开发基座)
Solon 框架! Solon 是新一代,Java 企业级应用开发框架.从零开始构建(No Java-EE),有灵活的接口规范与开放生态.采用商用友好的 Apache 2.0 开源协议,是" ...