当前位置: 首页 > news >正文

CF2143F Increasing Xor

我咋天天忘。还怎么学 OI 啊。

题意

给定长度为 \(n\) 的序列 \(a\)\(q\) 次询问给定 \(l,r\),每次查询提取出 \([l,r]\) 这段子区间,在这段子区间中你能执行任意次操作,每次操作任选 \(l\le i\le j\le r\) 然后 \(a_j\leftarrow a_i\oplus a_j\)。求是否存在一种方案使得 \(a_{l,\cdots,r}\) 严格递增。

\(\sum n,\sum q\le 2\times10^5,1\le a_i<2^{20}\)

分析

如果是全局查询,那么首先对每个位置 \(i\) 建出前 \(i\) 个元素的线性基,然后按照线性基有效元素个数分类分出 \(O(\log V)\) 类,每一类的线性基相同。对于每一类,假设前一类的最大值为 \(x\),这一类要填的长度为 \(len\),那么如果在这一类的线性基中 \(x\) 排名为 \(rk\),那么在这一类中我们就选取排名为 \(rk+1\)\(rk+len\) 之间的数,该类的末尾显然就是排名 \(rk+len\) 的数。而求线性基第 \(k\) 大和一个数 \(x\) 的排名都是基本操作,单次复杂度一个 log。

现在考虑区间查询,考虑前缀线性基,即每次插入一个数时保留时间戳靠后的数,然后将时间戳靠前的数往后插入。由于需要求有效元素个数,扫描线 \(l\) 删除出现时刻 \(<l\) 的数即可。总时间复杂度 \(O(n\log^2n)\)

点击查看代码
#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<algorithm>
#include<cmath>
#include<map>
#include<unordered_map>
#include<vector>
#include<queue>
#include<stack>
#include<bitset>
#include<set>
#include<array>
#include<tuple>
#include<ctime>
#include<random>
#include<cassert>
#include<chrono>
#define x1 xx1
#define y1 yy1
#define IOS ios::sync_with_stdio(false)
#define ITIE cin.tie(0)
#define OTIE cout.tie(0)
#define PY puts("Yes")
#define PN puts("No")
#define PW puts("-1")
#define P0 puts("0")
#define P__ puts("")
#define PU puts("--------------------")
#define mp make_pair
#define fi first
#define se second
#define gc getchar
#define pc putchar
#define pb emplace_back
#define un using namespace
#define il inline
#define all(x) x.begin(),x.end()
#define mem(x,y) memset(x,y,sizeof x)
#define popc __builtin_popcountll
#define rep(a,b,c) for(int a=(b);a<=(c);++a)
#define per(a,b,c) for(int a=(b);a>=(c);--a)
#define reprange(a,b,c,d) for(int a=(b);a<=(c);a+=(d))
#define perrange(a,b,c,d) for(int a=(b);a>=(c);a-=(d))
#define graph(i,j,k,l) for(int i=k[j];i;i=l[i].nxt)
#define lowbit(x) ((x)&-(x))
#define lson(x) ((x)<<1)
#define rson(x) ((x)<<1|1)
//#define double long double
//#define int long long
//#define int __int128
using namespace std;
using i64=long long;
using u64=unsigned long long;
using pii=pair<int,int>;
template<typename T1,typename T2>inline bool ckmx(T1 &x,T2 y){return x>=y?0:(x=y,1);}
template<typename T1,typename T2>inline bool ckmn(T1 &x,T2 y){return x<=y?0:(x=y,1);}
inline auto rd(){int qwqx=0,qwqf=1;char ch=getchar();while(ch<'0'||ch>'9'){if(ch=='-')qwqf=-1;ch=getchar();}while(ch>='0'&&ch<='9'){qwqx=(qwqx<<1)+(qwqx<<3)+ch-48;ch=getchar();}return qwqx*qwqf;
}
template<typename T>inline void write(T qwqx,char ch='\n'){if(qwqx<0){qwqx=-qwqx;putchar('-');}int qwqy=0;static char qwqz[40];while(qwqx||!qwqy){qwqz[qwqy++]=qwqx%10+48;qwqx/=10;}while(qwqy--){putchar(qwqz[qwqy]);}if(ch)putchar(ch);
}
bool Mbg;
const int mod=998244353;
template<typename T1,typename T2>inline void adder(T1 &x,T2 y){x+=y,x=x>=mod?x-mod:x;}
template<typename T1,typename T2>inline void suber(T1 &x,T2 y){x-=y,x=x<0?x+mod:x;}
const int maxn=2e5+5,inf=0x3f3f3f3f;
const long long llinf=0x3f3f3f3f3f3f3f3f;
const int m=19;
int n,Q,a[maxn];
struct Basis{int b[m+1],tim[m+1],tot;il void init(){mem(b,0),mem(tim,0),tot=0;}il void ins(int x,int t){per(i,m,0)if((x>>i)&1){if(!b[i])return b[i]=x,tim[i]=t,++tot,void();if(t>tim[i])swap(b[i],x),swap(tim[i],t);x^=b[i];}}il int qry(int lft,int k){--k;if(k<=0)return 0;int num=0;rep(i,0,m)if(tim[i]>=lft)++num;int res=0;per(i,m,0)if(tim[i]>=lft){if((k>>(num-1))&1)ckmx(res,res^b[i]);else ckmn(res,res^b[i]);--num;}return res;}//小于等于x的数有几个 il int getrk(int lft,int x){if(x<0)return 0;vector<int>v(m+1,0);rep(i,0,m)if(tim[i]>=lft)v[i]=1;rep(i,1,m)v[i]+=v[i-1];int res=0,nw=0;per(i,m,0){if(tim[i]>=lft){if((x>>i)&1){nw+=1<<(v[i]-1);ckmx(res,res^b[i]);}else{ckmn(res,res^b[i]);}}else{if(((res>>i)&1)&&(~(x>>i)&1))return nw;}}return nw+1;}void operator=(const Basis &p){tot=p.tot;rep(i,0,m)b[i]=p.b[i],tim[i]=p.tim[i];}
} c[maxn];
vector<pii>ql[maxn];
vector<int>vec[maxn],v;
struct pq{priority_queue<int>q1,q2;void clear(){while(!q1.empty())q1.pop();while(!q2.empty())q2.pop();}void push(int x){q1.push(x);}void erase(int x){q2.push(x);}bool empty(){while(!q1.empty()&&!q2.empty()&&q1.top()==q2.top())q1.pop(),q2.pop();return q1.empty();}int top(){assert(!q1.empty());return q1.top();}
}q[m+2];
bool ans[maxn];
void init(){rep(i,0,n)c[i].init(),ql[i].clear(),vec[i].clear();rep(i,0,m+1)q[i].clear();
}
inline void solve_the_problem(){n=rd(),Q=rd(),init();rep(i,1,n)a[i]=rd();rep(i,1,n)c[i]=c[i-1],c[i].ins(a[i],i);]rep(i,1,n)rep(j,0,m)if(c[i].tim[j])vec[c[i].tim[j]].pb(i);rep(i,1,Q){int l=rd(),r=rd();ql[l].pb(mp(r,i));}rep(i,1,n)q[c[i].tot].push(i);rep(l,1,n){for(int i:vec[l-1]){q[c[i].tot].erase(i);--c[i].tot;q[c[i].tot].push(i);}for(pii _:ql[l]){int r=_.fi,id=_.se;v.clear();for(int i=1;i<=m+1&&!q[i].empty();++i){int p=q[i].top();v.pb(min(p,r));if(p>r)break;}bool ok=1;int lst=l-1,ed=-1;rep(i,0,(int)v.size()-1){int len=v[i]-lst;lst=v[i];int rk=c[v[i]].getrk(l,ed);if(rk+len>(1<<c[v[i]].tot)){ok=0;break;}ed=c[v[i]].qry(l,rk+len);}ans[id]=ok;}}rep(i,1,Q)ans[i]?PY:PN;
}
bool Med;
signed main(){
//	freopen(".in","r",stdin);freopen(".out","w",stdout);fprintf(stderr,"%.3lfMB\n",(&Mbg-&Med)/1048576.0);int _=rd();while(_--)solve_the_problem();
}
/**/
http://www.hskmm.com/?act=detail&tid=10015

相关文章:

  • 提到链接,你能想到什么
  • 实用指南:容器逃逸漏洞
  • 三种方式处理SpringBoot全局异常
  • ECT-OS-JiuHuaShan 框架的元推理,是历史性的文明话语权
  • 应对连写与变体:深度学习赋能维吾尔文识别的核心方案与难点解析
  • CMake工具链
  • 20250918 - NGP Token 攻击事件:价格维持机制为攻击者做了嫁衣
  • 【脑电分析系列】第6篇:经典ERP成分解析 — P300、N170、N400等波形与它们代表的认知功能 — 洞察大脑的认知“电信号语言” - 教程
  • 9.19
  • [GDKOI2023 提高组] 游戏 题解
  • CSP-J/S 2025 游记
  • 2025.9.19 计数dp小记
  • Odoo19.0发布、微信支付、支付宝支付和顺丰模块同步上线
  • 9月14-21日小记 - L
  • ctfshow web入门 命令执行
  • 解题记录说是 | P3695 CYaRon!语
  • 分享一个极度精简的绿色的 五笔输入法
  • 实用指南:AI推理范式:从CoT到ReAct再到ToT的进化之路
  • sign up - Gon
  • ctfshow web入门 信息搜集
  • 完整教程:数据结构:单链表的应用(力扣算法题)第二章
  • CF2039E Shohag Loves Inversions
  • U522155 板垣 カノエ is WATCHING YOU std
  • ctfshow web
  • 代码随想录算法训练营第三天 | leetcode 203 707 206
  • Codeforces Round 1051 (Div. 2) A~D2
  • 【F#学习】数组:Array
  • CTFWEB姿势总结
  • 规模化加速AI:从用户、开发者到企业的深度策略解析
  • ctfshow 菜狗杯