省选模拟39

然后我又垫底了......

不想写题解ing

T1 逃离藏宝洞

发现可以每次跳个40步,然后因为一定是先上升再下降的,所以我们可以跳到路径最高点!!

期望步数是一半!!

AC_code
#include<bits/stdc++.h>
#include"escape.h"
using namespace std;
#define fo(i,x,y) for(int i=(x);i<=(y);i++)
#define fu(i,x,y) for(int i=(x);i>=(y);i--)
int read(){
    int s=0,t=1;char ch=getchar();
    while(!isdigit(ch)){if(ch=='-')t=-1;ch=getchar();}
    while(isdigit(ch)){s=(s<<1)+(s<<3)+(ch^48);ch=getchar();}
    return s*t;
}
int now,las;
void spj1(){
    bool fl=false;
    move(0);fl=true;las=0;
    if(query()<now)move(0),fl=false;
    if(!fl){
        move(1);fl=true;las=1;
        if(query()<now)move(1),fl=false;
    }
    if(!fl){move(2);las=2;}
    now++;
    while(now){
        if(las==0){
            move(1);fl=true;las=1;
            if(query()<now)move(1),fl=false;
            if(!fl)move(2),las=2;
            now++;
        }
        else if(las==1){
            move(0);fl=true;las=0;
            if(query()<now)move(0),fl=false;
            if(!fl)move(2),las=2;
            now++;
        }
        else if(las==2){
            move(1);fl=true;las=1;
            if(query()<now)move(1),fl=false;
            if(!fl)move(0),las=0;
            now++;
        }
    }
}
random_device you;
mt19937 pyt(you());
int rd(int l,int r){
    uniform_int_distribution<> ee(l,r);
    return ee(pyt);
}
int ji[100],cj,lim;
int ano(int x){
    return x==0?1:(x==1?2:0);
}
void jump(){
    cj=0;ji[0]=las;
    // cerr<<now<<" "<<query()<<endl;
    fo(i,1,lim){
        int tmp=ji[cj];
        ji[++cj]=pyt()%2?ano(tmp):ano(ano(tmp));
        // cerr<<ji[cj]<<endl;
        if(ji[cj]==ji[cj-1])ji[cj]=0;
        assert(ji[cj]>=0&&ji[cj]<=2);
        move(ji[cj]);
        // cerr<<ji[cj]<<" "<<ji[cj-1]<<" "<<query()<<endl;
    }
    // cerr<<endl;
    int res=query(),tmp=res;
    // cerr<<res<<endl;
    // cerr<<now<<" "<<lim<<" "<<res<<endl;
    // cerr<<"SB"<<" "<<(now+lim-tmp>>1)<<endl;
    fo(i,1,(now+lim-tmp)>>1){
        // cerr<<cj<<endl;
        assert(ji[cj]>=0&&ji[cj]<=2);
        move(ji[cj--]),res++;
    }
    now=res;
    // cerr<<now<<" "<<query()<<" ";
    // cerr<<cj<<endl;
    if(cj!=lim){
        if(ji[cj]!=0&&ji[cj+1]!=0)move(0),las=0;
        if(ji[cj]!=1&&ji[cj+1]!=1)move(1),las=1;
        if(ji[cj]!=2&&ji[cj+1]!=2)move(2),las=2;
        now++;
    }
    else las=ji[cj];
    // cerr<<query()<<" "<<now<<endl;
    // exit(0);
}
void escape(int lm, int lq){
    now=query();
    if(lq>=-now){spj1();return ;}
    bool fl;lim=lm/(-now)/2;
    move(0);fl=true;las=0;
    if(query()<now)move(0),fl=false;
    if(!fl){
        move(1);fl=true;las=1;
        if(query()<now)move(1),fl=false;
    }
    if(!fl){move(2);las=2;}
    now++;
    // cerr<<now<<" "<<query()<<" "<<las<<endl;
    while(now<0)jump();
}

T2 序列划分

线段树模板题

AC_code
#include<bits/stdc++.h>
using namespace std;
#define int long long
#define fo(i,x,y) for(int i=(x);i<=(y);i++)
#define fu(i,x,y) for(int i=(x);i>=(y);i--)
int read(){
    int s=0,t=1;char ch=getchar();
    while(!isdigit(ch)){if(ch=='-')t=-1;ch=getchar();}
    while(isdigit(ch)){s=(s<<1)+(s<<3)+(ch^48);ch=getchar();}
    return s*t;
}
const int N=1e6+5;
const int mod=998244353;
int ksm(int x,int y){
    int ret=1;
    while(y){
        if(y&1)ret=ret*x%mod;
        x=x*x%mod;y>>=1;
    }return ret;
}
int n,a[N],mex[N],nxt[N],vis[N];
struct XDS{
    #define ls x<<1
    #define rs x<<1|1
    int mn[N*4],tg[N*4],sn[N*4];
    int sm[N*4],ts[N*4],tj[N*4];
    void pushup(int x){
        mn[x]=min(mn[ls],mn[rs]);
        sn[x]=(sn[ls]+sn[rs])%mod;
        // sm[x]=(sm[ls]+sm[rs])%mod;
        return ;
    }
    void pushdown(int x,int l,int r){
        int mid=l+r>>1;
        if(tj[x]){
            tj[ls]=(tj[ls]+tj[x])%mod;
            if(mid==l)sm[ls]=(sm[ls]+tj[x]*(mid-l+1))%mod;
            tj[rs]=(tj[rs]+tj[x])%mod;
            if(r==mid+1)sm[rs]=(sm[rs]+tj[x]*(r-mid))%mod;
            tj[x]=0;
        }
        if(ts[x]){
            if(~tg[ls])tj[ls]=(tj[ls]+ts[x]*mn[ls])%mod;
            else ts[ls]=(ts[ls]+ts[x])%mod;
            if(mid==l)sm[ls]=(sm[ls]+sn[ls]*ts[x])%mod;
            if(~tg[rs])tj[rs]=(tj[rs]+ts[x]*mn[rs])%mod;
            else ts[rs]=(ts[rs]+ts[x])%mod;
            if(r==mid+1)sm[rs]=(sm[rs]+sn[rs]*ts[x])%mod;
            ts[x]=0;
        }
        if(~tg[x]){
            tg[ls]=mn[ls]=tg[x];
            if(l==mid)sn[ls]=tg[x]*(mid-l+1)%mod;
            tg[rs]=mn[rs]=tg[x];
            if(r==mid+1)sn[rs]=tg[x]*(r-mid)%mod;
            tg[x]=-1;
        }
        tg[x]=-1;return ;
    }
    void build(int x,int l,int r){
        tg[x]=-1;ts[x]=tj[x]=0;
        if(l==r){
            sm[x]=mn[x]=sn[x]=mex[l];
            return ;
        }
        int mid=l+r>>1;
        build(ls,l,mid);
        build(rs,mid+1,r);
        pushup(x);return ;
    }
    int query(int x,int l,int r,int qr,int v){
        if(r<=qr){
            if(mn[x]>=v){
                tg[x]=v;mn[x]=v;
                sn[x]=v*(r-l+1)%mod;
                return l;
            }
            if(l==r)return r+1;
            int mid=l+r>>1,ret=0;
            if(~tg[x]||tj[x]||ts[x])pushdown(x,l,r);
            ret=query(rs,mid+1,r,qr,v);
            if(ret==mid+1)ret=query(ls,l,mid,qr,v);
            pushup(x);return ret;
        }
        int mid=l+r>>1,ret=0;
        if(~tg[x]||tj[x]||ts[x])pushdown(x,l,r);
        if(qr>mid)ret=query(rs,mid+1,r,qr,v);
        if(!ret||ret==mid+1)ret=query(ls,l,mid,qr,v);
        pushup(x);return ret;
    }
    void ins_sm(int x,int l,int r,int ql,int qr,int v){
        if(ql<=l&&r<=qr){
            if(~tg[x])tj[x]=(tj[x]+v*mn[x])%mod;
            else ts[x]=(ts[x]+v)%mod;
            sm[x]=(sm[x]+v*sn[x])%mod;
            return ;
        }
        int mid=l+r>>1;
        if(~tg[x]||tj[x]||ts[x])pushdown(x,l,r);
        if(ql<=mid)ins_sm(ls,l,mid,ql,qr,v);
        if(qr>mid)ins_sm(rs,mid+1,r,ql,qr,v);
        pushup(x);return ;
    }
    int qry(int x,int l,int r,int ql,int qr){
        if(ql<=l&&r<=qr)return sm[x];
        int mid=l+r>>1,ret=0;
        if(~tg[x]||tj[x]||ts[x])pushdown(x,l,r);
        if(ql<=mid)ret=(ret+qry(ls,l,mid,ql,qr))%mod;
        if(qr>mid)ret=(ret+qry(rs,mid+1,r,ql,qr))%mod;
        pushup(x);return ret;
    }
    #undef ls
    #undef rs
}xds;
signed main(){
    freopen("divide.in","r",stdin);
    freopen("divide.out","w",stdout);
    // cerr<<(sizeof(xds)+sizeof(a)*5>>20)<<endl;
    n=read();
    fo(i,1,n)a[i]=read();
    fo(i,1,n){
        if(a[i]<=n){
            nxt[vis[a[i]]]=i;
            vis[a[i]]=i;
        }
        mex[i]=mex[i-1];
        while(vis[mex[i]])mex[i]++;
    }
    xds.build(1,1,n);
    fo(i,1,n-1){
        if(!nxt[i])nxt[i]=n+1;
        if(a[i]<=n)xds.query(1,1,n,nxt[i]-1,a[i]);
        int now=xds.qry(1,1,n,i,i);
        xds.ins_sm(1,1,n,i+1,n,now);
    }
    printf("%lld",xds.qry(1,1,n,n,n));
    return 0;
}

T3 重排列

考场上一直在想如何贪心,但是还是没有找到一个符合两个人策略的最优解

发现B是不能改变两个不互质的数的相对顺序的

所以我们先给不互质的数连边,我们会形成许多个联通块,这些联通块之间是互相独立的

如果求出来每个联通块的顺序,用优先队列合并就好了

那么在一个联通块中我们肯定选最小的那个,于是删掉他,递归解决!!

不要看码,我是智障写了120

AC_code
#include<bits/stdc++.h>
using namespace std;
#define fo(i,x,y) for(int i=(x);i<=(y);i++)
#define fu(i,x,y) for(int i=(x);i>=(y);i--)
int read(){
    int s=0,t=1;char ch=getchar();
    while(!isdigit(ch)){if(ch=='-')t=-1;ch=getchar();}
    while(isdigit(ch)){s=(s<<1)+(s<<3)+(ch^48);ch=getchar();}
    return s*t;
}
const int N=2005;
int n,a[N],ans[N*2][N],cas;
struct node{
    int v,bl,tp;
}nd[N*20];
int cnd;
struct E{int to,nxt;}e[N*20];
int head[N*20],rp;
void add_edg(int x,int y){e[++rp].to=y;e[rp].nxt=head[x];head[x]=rp;}
map<int,int> mp;
bool ban[N*20],ok[N*20];
struct nod{
    int v,id;
    bool operator < (nod a)const{
        return ans[id][v]<ans[a.id][a.v];
    }
};
void dfs(int x,int v,int las,int mn,int d){
    // cerr<<x<<" "<<d<<" "<<v<<" "<<nd[x].v<<" "<<las<<endl;
    if(nd[x].bl!=las||ban[x])return ;
    nd[x].bl=v;
    if(d)ok[x]=true;
    for(int i=head[x];i;i=e[i].nxt){
        int y=e[i].to;
        if(y==mn)ok[x]=true;
        if(nd[y].bl!=las||ban[y])continue;
        dfs(y,v,las,mn,(d&&x>n));
    }
}
int gcd(int x,int y){return !y?x:gcd(y,x%y);}
void sol(int x,int f,int las){
    // cerr<<"sol"<<" "<<x<<" "<<f<<endl;
    int mn=-1;
    fo(i,1,n){
        if(x==0){mn=0;break;}
        // cerr<<i<<" "<<nd[i].bl<<endl;
        if(ban[i]||(gcd(nd[i].v,nd[las].v)==1&&nd[i].v!=1&&nd[las].v!=1)||nd[i].bl!=x)continue;
        // cerr<<nd[i].v<<endl;
        if(mn==-1||nd[i].v<nd[mn].v)mn=i;
    }
    // cerr<<mn<<endl;
    if(mn==-1)return ;
    ans[x][++ans[x][0]]=nd[mn].v;
    ban[mn]=true;
    // cerr<<"ZZ"<<" "<<x<<" "<<ans[x][1]<<endl;
    fo(i,0,n)if(nd[i].bl==x)ok[i]=false;
    priority_queue<nod> q;
    for(int i=head[mn];i;i=e[i].nxt){
        int y=e[i].to;
        if(nd[y].bl!=x)continue;
        // cerr<<y<<" "<<x<<endl;
        cas++;int tmp=cas;
        dfs(y,tmp,x,mn,1);
        sol(tmp,x,mn);
        if(!ans[tmp][0])continue;
        q.push(nod{1,tmp});
    }
    // cerr<<endl;
    // cerr<<"W"<<" "<<x<<" "<<f<<endl;
    while(!q.empty()){
        nod now=q.top();q.pop();
        // cerr<<ans[now.id][now.v]<<" "<<now.id<<" "<<now.v<<endl;
        ans[x][++ans[x][0]]=ans[now.id][now.v];
        if(now.v==ans[now.id][0])continue;
        q.push(nod{now.v+1,now.id});
    }
    // fo(i,1,ans[x][0])cerr<<ans[x][i]<<" ";
    // cerr<<endl;
}
signed main(){
    freopen("permutation.in","r",stdin);
    freopen("permutation.out","w",stdout);
    n=cnd=read();
    fo(i,1,n){
        a[i]=read();
        nd[i].v=a[i];
        nd[i].tp=1;
        nd[i].bl=0;
        int now=a[i];
        for(int j=2;j*j<=now;j++){
            if(now%j==0){
                if(!mp[j]){
                    mp[j]=++cnd;
                    nd[cnd].v=j;
                    nd[cnd].tp=0;
                    nd[cnd].bl=0;
                }
                add_edg(i,mp[j]);
                add_edg(mp[j],i);
            }
            while(now%j==0)now/=j;
        }
        if(now!=1){
            if(!mp[now]){
                mp[now]=++cnd;
                nd[cnd].v=now;
                nd[cnd].tp=0;
                nd[cnd].bl=0;
            }
            add_edg(i,mp[now]);
            add_edg(mp[now],i);
        }
    }
    fo(i,1,cnd){
        add_edg(0,i),add_edg(i,0);
        ok[i]=true;
    }ok[0]=true;
    sol(0,0,0);
    fo(i,2,n+1)printf("%d ",ans[0][i]);
}
posted @ 2022-03-28 19:30  fengwu2005  阅读(49)  评论(0编辑  收藏  举报