爆
现在处于非常破防的阶段,不知道为什么会打成这个样子。
ABC 过得很快。看到 D1 的第一眼就会了,发现转移只需要随便优化一下就能通过 D2,不太想写。E 看上去挺可做,F 看上去是板子题。于是开始写 F,不知道这种代码不长、没有任何思维难度的题怎么能写那么长时间,根本原因是没有认真阅读论文。
破防。
破防。
破防。
破防。
D
充要条件是 LDS 长度至多为 \(2\),考察结构,形如一个上升序列接上一个下降的数,需要满足每段峰值递增,下降的数递增。令 \(f_{i,j}\) 代表峰值为 \(i\),下降的数为 \(j\) 的方案数,转移一定从左下角转移过来,同时转移系数只和 \((j',i)\) 相关,树状数组直接维护。
感觉本质可以算为 1D-1D 的 dp。
E
没细想,无非是南京站 B 的套路。
F
考虑判定,求出线性基后一定是从后往前贪心填,求线性基只需 cxy 论文里的前缀线性基(CF1100F)。
ABC 过不了 DFA 题,CF 过不了线性基题,这种人是不配进省队的。
请认真学习线性基求 kth
#include<bits/stdc++.h>
#define int long long
#define fi first
#define se second
#define pii std::pair<int,int>
#define vint std::vector<int>
#define vpair std::vector<pii>
#define all(x) (x).begin(),(x).end()
#define SZ(x) (x).size()
#define debug(...) fprintf(stderr,##__VA_ARGS__)
template<typename T>
void read(T &x){
x=0;
int f=1;
char c=getchar();
while(c<'0'||c>'9'){
if(c=='-') f=-1;
c=getchar();
}
while(c>='0'&&c<='9') x=x*10+(int)(c-'0'),c=getchar();
x*=f;
}
std::stack<char>st;
template<typename T>
void print(T x){
if(x==0) putchar('0');
if(x<0) putchar('-'),x=-x;
while(st.size()) st.pop();
while(x) st.push((char)('0'+x%10)),x/=10;
while(st.size()) putchar(st.top()),st.pop();
}
template<typename T>
void printsp(T x){
print(x),putchar(' ');
}
template<typename T>
void println(T x){
print(x),putchar('\n');
}
template<typename T,typename I>
bool chkmin(T &a,I b){
if(a>b) return a=b,1;
return 0;
}
template<typename T,typename I>
bool chkmax(T &a,I b){
if(a<b) return a=b,1;
return 0;
}
template<typename T,typename I>
void addedge(std::vector<I>*vec,T u,T v){
vec[u].push_back(v);
}
template<typename T,typename I,typename K>
void addedge(std::vector<K>*vec,T u,T v,I w){
vec[u].push_back({v,w});
}
template<typename T,typename I>
void addd(std::vector<I>*vec,T u,T v){
addedge(vec,u,v),addedge(vec,v,u);
}
template<typename T,typename I,typename K>
void addd(std::vector<K>*vec,T u,T v,I w){
addedge(vec,u,v,w),addedge(vec,v,u,w);
}
bool Mbe;
const int inf=1e9,MOD1=998244353,MOD2=1e9+7;
const int maxn=2e5+10;
int n,a[maxn],T,ql[maxn],qr[maxn],ans[maxn],q;
vint vr[maxn];
struct basic{
int v[25],key[25],pos[25],num;
basic(){memset(v,0,sizeof(v)),memset(pos,0,sizeof(pos)),memset(key,0,sizeof(key)),num=0;}
int sz(){return (1<<num);}
void insert(int x,int y,int id){
for(int i=20;i>=0;i--){
if(((x>>i)&1)==0) continue;
if(!v[i]){
v[i]=x,key[i]=y,pos[i]=id;
return ;
}
if(key[i]<y) std::swap(x,v[i]),std::swap(key[i],y),std::swap(pos[i],id);
x^=v[i];
}
}
void rebuild(){
for(int i=0;i<=20;i++){
if(!v[i]) continue;
for(int j=0;j<i;j++) if(((v[i]>>j)&1)&&v[j]) v[i]^=v[j];
}
}
int kth(int k,int w){
int tot=0,x=0;
k--;
for(int i=0;i<=20;i++) if(key[i]>=w&&v[i]) tot++;
for(int i=20;i>=0;i--){
if(!v[i]) continue;
if(key[i]<w) continue;
tot--;
if((x>>i)&1){
if((1<<tot)<=k) k-=(1<<tot);
else x^=v[i];
}else{
if((1<<tot)<=k) k-=(1<<tot),x^=v[i];
}
}
return x;
}
int find(int x,int w){
int tot=0,ans=0,now=0;
for(int i=0;i<=20;i++) if(key[i]>=w&&v[i]) tot++;
if(x==inf) return (1<<tot);
for(int i=20;i>=0;i--){
if(v[i]&&key[i]>=w)tot--;
if((x>>i)&1){
if((!v[i])||key[i]<w){
if(((now>>i)&1)==0) return ans+(1<<tot);
continue;
}
ans+=(1<<tot),chkmax(now,now^v[i]);
}else{
if((!v[i])||key[i]<w){
if((now>>i)&1) return ans;
continue;
}
chkmin(now,now^v[i]);
}
}
return ans;
}
void Pr(){
for(int i=0;i<=20;i++)
if(v[i]) debug("i=%lld v=%lld key=%lld pos=%lld\n",i,v[i],key[i],pos[i]);
}
};
bool Men;
signed main(){
// freopen("in.in","r",stdin),freopen(".out","w",stdout);
debug("%.6lfMB\n",(&Mbe-&Men)/1048576.0);
read(T);
while(T--){
read(n),read(q);
for(int i=1;i<=n;i++) read(a[i]),vr[i].clear();
for(int i=1;i<=q;i++) read(ql[i]),read(qr[i]),vr[ql[i]].push_back(i);
basic B;
for(int i=n;i>=1;i--){
B.insert(a[i],-i,i);
for(int j:vr[i]){
ans[j]=1;
int r=qr[j];
vint pos;
for(int k=0;k<=20;k++) if(B.v[k]&&B.key[k]>=-r) pos.push_back(B.pos[k]);
std::sort(all(pos));
std::reverse(all(pos));
int laspos=r,lasv=inf;
for(int k:pos){
//k~laspos
if(lasv==0){
ans[j]=0;
break;
}
int p=B.find(lasv,-laspos);
if(p<laspos-k+1){
ans[j]=0;
break;
}
lasv=B.kth(p-(laspos-k+1)+1,-laspos);
laspos=k-1;
}
}
}
for(int i=1;i<=q;i++)
if(ans[i]) printf("Yes\n");
else printf("No\n");
}
debug("%.6lfms\n",1e3*clock()/CLOCKS_PER_SEC);
}
/*
1
10 1
3 9 10 6 6 1 6 1 4 6
5 10
*/
破防,怎么能打成这个样子。
破防破防破防破防。