现在处于非常破防的阶段,不知道为什么会打成这个样子。

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
*/

破防,怎么能打成这个样子。

破防破防破防破防。

posted @ 2025-09-18 02:32  BYR_KKK  阅读(26)  评论(1)    收藏  举报