10.5 模拟赛

前言

业精于勤荒于嬉,行成于思毁于随

正文(模拟赛)

卦象:凶

感受:开 T1,第一眼读错题,白费 20min;第二眼简单区间 DP,没打算写,然后先去开 T2,为爆零埋下了伏笔。九点开 T2,一顿手模之后发现链式结构,此时九点半,开写 T2。写到比赛结束都没有调出来,最后 T1 也没来得及写,原地爆炸

T1

简单区间 DP 题,记 \(f_{l,r}\) 表示区间 \([l,r]\) 内的答案,其实未必要合并成一个数,我们只关心单次合并对答案的贡献

转移显然枚举断点,只在 \(len-1 \equiv 0 \pmod {k-1}\) 的时候进行区间合并的贡献统计

也没什么细节问题,时间复杂度 \(O(n^3/k)\)

点击查看代码
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N=505;
int n,k,a[N],s[N],f[N][N];
inline void chkmn(int &x,int y){x=min(x,y);return;}
inline int ask(int l,int r){return s[r]^s[l-1];}
signed main(){
    freopen("merge.in","r",stdin);
    freopen("merge.out","w",stdout);
    cin>>n>>k;
    for(int i=1;i<=n;i++)cin>>a[i];
    for(int i=1;i<=n;i++)s[i]=s[i-1]^a[i];
    memset(f,0x3f,sizeof(f));
    for(int i=1;i<=n;i++)f[i][i]=0;
    for(int len=2;len<=n;len++){
        for(int l=1;l+len-1<=n;l++){
            int r=l+len-1;
            for(int p=l;p<=r-1;p+=(k-1))chkmn(f[l][r],f[l][p]+f[p+1][r]);
            if((len-1)%(k-1)==0)f[l][r]+=ask(l,r);
        }
    }
    cout<<f[1][n]<<'\n';
    return 0;
}

T2

发现链式结构,被二分创飞了

点击查看代码
#include<bits/stdc++.h>
#define pii pair<int,int>
#define fi first
#define se second
#define mkp make_pair
#define vp vector<pii>
#define pb push_back
#define lwbd lower_bound
using namespace std;
const int N=1e6+5;
int n,m,Q,a[N][2];
struct que{int l,r,k,id;}q[N];
pii pre[N][2],mp[N],f[N][2];
vp vec[N<<1],pos[N];int tol;
int rev[N][2];bool vis[N][2];
inline pii fnd(int x,int lim){
    int l=0,r=pos[x].size()-1,id=-1;
    while(l<=r){
        int mid=(l+r)>>1;
        if(pos[x][mid].fi<=lim)l=mid+1,id=mid;
        else r=mid-1;
    }
    return (id==-1?mkp(-1,-1):pos[x][id]);
}
inline pii fnd2(vp vec,int x){
    int l=0,r=vec.size()-1,res=-1;
    while(l<=r){
        int mid=(l+r)>>1;
        if(vec[mid].fi>=x)r=mid-1,res=mid;
        else l=mid+1;
    }
    return vec[res];
}
int main(){
    freopen("perm.in","r",stdin);
    freopen("perm.out","w",stdout);
    ios::sync_with_stdio(0);
    cin.tie(0),cout.tie(0);
    cin>>n>>m>>Q;
    for(int i=1;i<=m;i++)cin>>a[i][0]>>a[i][1];
    for(int i=1;i<=m;i++){
        if(a[i][0]==a[i][1])continue;
        pos[a[i][0]].pb(mkp(i,0)),pos[a[i][1]].pb(mkp(i,1));
    }
    for(int i=1;i<=m;i++){
        if(a[i][0]==a[i][1])continue;
        pre[i][0]=mp[a[i][0]],mp[a[i][0]]=mkp(i,0);
        pre[i][1]=mp[a[i][1]],mp[a[i][1]]=mkp(i,1);
    }
    for(int i=1;i<=m;i++)f[i][0]=pre[i][1],f[i][1]=pre[i][0];
    for(int i=m;i>=1;i--){
        if(a[i][0]==a[i][1])continue;
        for(int o=0;o<=1;o++){
            pii p=mkp(i,o);
            if(vis[p.fi][p.se])continue;
            tol++;
            while(p.fi){
                vec[tol].pb(p),rev[p.fi][p.se]=tol,vis[p.fi][p.se]=true;
                p=f[p.fi][p.se];
            }
        }
    }
    for(int i=1;i<=tol;i++)sort(vec[i].begin(),vec[i].end());
    while(Q--){
        int l,r,k;cin>>l>>r>>k;
        pii idx=fnd(k,r);
        if(idx.fi==-1||idx.fi<l){cout<<k<<'\n';continue;}
        int c=rev[idx.fi][idx.se];
        pii ans=fnd2(vec[c],l);
        cout<<a[ans.fi][ans.se^1]<<'\n';
    }
    return 0;
}

T3

初始化 \(f_i \gets + \infty\)

如果当前有向图上存在无出度的点 \(v\),对于所有的 \((u,v) \in E\),进行 \(\operatorname{chkmn}(f_u,\max(f_v-p,r))\)

否则,挑出 \(r\) 最大的边 \((u,v,r,p)\),进行 \(\operatorname{chkmn}(f_u,r)\)

重复执行“如果……否则……”,直到所有边都被删除

点击查看代码
#include<bits/stdc++.h>
#define int long long
#define pii pair<int,int>
#define fi first
#define se second
#define mkp make_pair
#define vi vector<int>
#define vn vector<NODE>
#define pb push_back
using namespace std;
const int N=2e5+5,INF=9e18,V=1e18;
int n,m,out[N],f[N],q[N],hd=1,tl=0;
struct NODE{int v,r,p,id;};vn G[N];
struct edge{int u,v,r,p;}e[N];
bool mrk[N];
inline bool cmp(edge x,edge y){return x.r>y.r;}
inline void chkmn(int &x,int y){x=min(x,y);return;}
inline void work(){
    while(hd<=tl){
        int u=q[hd++];
        for(auto E:G[u]){
            int v=E.v,r=E.r,p=E.p,id=E.id;
            if(mrk[id])continue;
            chkmn(f[v],max(r,f[u]-p));
            mrk[id]=true;out[v]--;
            if(!out[v])q[++tl]=v;
        }
    }
    return;
}
signed main(){
    freopen("walk.in","r",stdin);
    freopen("walk.out","w",stdout);
    ios::sync_with_stdio(0);
    cin.tie(0),cout.tie(0);
    cin>>n>>m;
    for(int i=1,u,v,r,p;i<=m;i++){
        cin>>u>>v>>r>>p;out[u]++;
        e[i]={u,v,r,p};
    }
    for(int i=1;i<=n;i++)f[i]=INF;
    for(int i=1;i<=n;i++)
        if(!out[i])q[++tl]=i;
    sort(e+1,e+m+1,cmp);
    for(int i=1;i<=m;i++){
        int u=e[i].u,v=e[i].v,r=e[i].r,p=e[i].p;
        G[v].pb({u,r,p,i});
    }
    work();
    for(int i=1;i<=m;i++){
        if(mrk[i])continue;
        int u=e[i].u,r=e[i].r;chkmn(f[u],r);
        mrk[i]=true;out[u]--;
        if(!out[u]){q[++tl]=u;work();}
    }
    for(int i=1;i<=n;i++)cout<<(f[i]>V?-1:f[i])<<' ';
    cout<<'\n';
    return 0;
}

T4

留坑待填

小结

补题效率不错,就是赛时表现太抽象了

后记

世界孤立我任它奚落

完结撒花!

posted @ 2025-10-05 19:58  sunxuhetai  阅读(10)  评论(0)    收藏  举报