2024“钉耙编程”中国大学生算法设计超级联赛(3)

· · 个人记录

比特跳跃

思路:由于到达每个点,其实只需要使用一次穿越,且如果使用穿越,必然是从其子集来到当前点,不然的话肯定是从1到当前点更优,那么先跑一次djstl,然后枚举子集即可,复杂度nlogn,后面再进行一次djstl跑完图,得到答案必然是最优的

diamond:

#include<bits/stdc++.h>
using namespace std;
#define int long long
#define PII pair<int,int>
vector<PII>mp[150005];
int n,m,k;
int dist[150001];
bool st[155001];
void djstl(){
    dist[1]=0;
    priority_queue<PII,vector<PII>,greater<PII>>q;
    for (int i = 1; i <=n ; ++i) {
        st[i]=0;
        if(dist[i]!=1e15)q.push({dist[i],i});
    }
    q.push({0,1});
    while(!q.empty()){
        auto t=q.top();
        q.pop();
        int ver=t.second,ds=t.first;
        if(st[ver])continue;
        st[ver]= true;
        for (int i = 0; i <mp[ver].size() ; ++i) {
            auto p=mp[ver][i];
            if(dist[p.first]>ds+p.second){
                dist[p.first]=ds+p.second;
                q.push({dist[p.first],p.first});
            }
        }
    }
}
void solve(){
    cin>>n>>m>>k;
    for (int i = 1; i <=n ; ++i) {
        mp[i].clear();
        dist[i]=1e15;
    }
    for (int i = 0; i <m ; ++i) {
        int x,y,z;
        cin>>x>>y>>z;
        mp[x].push_back({y,z});
        mp[y].push_back({x,z});
    }
    djstl();
    for (int i = 1; i <=n ; ++i) {
        dist[i]=min(dist[i],(i|1)*k);
        for (int j = (i-1)&i; j  ; j=(j-1)&i) {
            dist[i]=min(dist[i],dist[j]+i*k);
        }
    }
    djstl();
    for (int i = 2; i <=n ; ++i) {
        cout<<dist[i]<<" ";
    }
    cout<<endl;
}
signed main(){
    ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);

    int t;
    cin>>t;
    while(t--){
        solve();
    }
}

单峰数列

思路:线段树维护区间是否为升序和降序,由于合并时需要用到区间的端点的值,那么再维护一个最大值最小值,然后判断单峰用到最大值左边升序,右边降序即可

diamond:

#include<bits/stdc++.h>
using namespace std;
#define int long long
#define endl '\n'
#define N 100003
#define LD (o<<1)
#define RD (o<<1|1)
#define INF 0x7fffffff
struct Node{
    int l,r;
    int maxv,minv,issheng,isjiang;
    int add;
};
int n;
struct Tree{
    Node t[N<<2];
    int a[N];
    inline void pushup(Node &o,Node &ld,Node &rd){
        o.maxv=max(ld.maxv,rd.maxv);
        o.minv=min(ld.minv,rd.minv);
        if(ld.issheng and rd.issheng and ld.maxv<rd.minv){
            o.issheng=1;
        }
        else o.issheng=0;
        if(ld.isjiang and rd.isjiang and ld.minv>rd.minv){
            o.isjiang=1;
        }
        else o.isjiang=0;

    }
    inline void pushdown(Node &o,Node &ld,Node &rd){
        ld.add+=o.add;ld.maxv+=o.add;
        rd.add+=o.add;rd.maxv+=o.add;
        ld.minv+=o.add;
        rd.minv+=o.add;
        o.add=0;
    }
    void build(int o,int l,int r){
        t[o].l=l;t[o].r=r;t[o].add=0;
        if(l==r){t[o]={l,r,a[l],a[r],1,1,0};return;}
        int mid=(l+r)>>1;
        build(LD,l,mid);
        build(RD,mid+1,r);
        pushup(t[o],t[LD],t[RD]);
    }
    void update(int o,int l,int r,int v){
        if(l<=t[o].l&&t[o].r<=r){t[o].add+=v;t[o].maxv+=v,t[o].minv+=v;return;}
        pushdown(t[o],t[LD],t[RD]);
        int mid=(t[o].l+t[o].r)>>1;
        if(mid>=l)update(LD,l,r,v);
        if(mid<r)update(RD,l,r,v);
        pushup(t[o],t[LD],t[RD]);
    }
    int querymax(int o,int l,int r){
        if(l<=t[o].l&&t[o].r<=r)return t[o].maxv;
        pushdown(t[o],t[LD],t[RD]);
        int ans=LLONG_MIN/2,mid=(t[o].l+t[o].r)>>1;
        if(mid>=l)ans=max(ans,querymax(LD,l,r));
        if(mid<r)ans=max(ans,querymax(RD,l,r));
        pushup(t[o],t[LD],t[RD]);
        return ans;
    }
    int querymin(int o,int l,int r){
        if(l<=t[o].l&&t[o].r<=r)return t[o].minv;
        pushdown(t[o],t[LD],t[RD]);
        int ans=LLONG_MAX/2,mid=(t[o].l+t[o].r)>>1;
        if(mid>=l)ans=min(ans,querymin(LD,l,r));
        if(mid<r)ans=min(ans,querymin(RD,l,r));
        pushup(t[o],t[LD],t[RD]);
        return ans;
    }
    int querysheng(int o,int l,int r){
        if(l<=t[o].l&&t[o].r<=r)return t[o].issheng;
        pushdown(t[o],t[LD],t[RD]);
        int mid=(t[o].l+t[o].r)>>1;
        if(r<=mid){
            int d=querysheng(LD,l,r);
            pushup(t[o],t[LD],t[RD]);
            return d;
        }
        if(l>mid){
            int d=querysheng(RD,l,r);;
            pushup(t[o],t[LD],t[RD]);
            return d;
        }
        int d1= querysheng(LD,l,r);
        int d2= querysheng(RD,l,r);
        pushup(t[o],t[LD],t[RD]);
        if(d1 and d2 and querymax(LD,l,r)< querymin(RD,l,r)){
            return 1;
        }
        return 0;
    }
    int queryjiang(int o,int l,int r){
        if(l<=t[o].l&&t[o].r<=r)return t[o].isjiang;
        pushdown(t[o],t[LD],t[RD]);
        int mid=(t[o].l+t[o].r)>>1;
        if(r<=mid){
            int d=queryjiang(LD,l,r);
            pushup(t[o],t[LD],t[RD]);
            return d;
        }
        if(l>mid){
            int d=queryjiang(RD,l,r);;
            pushup(t[o],t[LD],t[RD]);
            return d;
        }
        int d1= queryjiang(LD,l,r);
        int d2= queryjiang(RD,l,r);
        pushup(t[o],t[LD],t[RD]);
        if(d1 and d2 and querymin(LD,l,r)> querymax(RD,l,r)){
            return 1;
        }
        return 0;
    }

}A;
signed main(){
    ios::sync_with_stdio(false),cin.tie(0);
    int q;
    cin>>n;
    for(int i=1;i<=n;i++)cin>>A.a[i];
    A.build(1,1,n);
    cin>>q;
    while(q--){
        int op,l,r;
        cin>>op>>l>>r;
        if(op==1){
            int x;
            cin>>x;
            A.update(1,l,r,x);
        }
        else if(op==2){
            cout<<(A.querymax(1,l,r)==A.querymin(1,l,r))<<endl;
        }
        else if(op==3){
            cout<<A.querysheng(1,l,r)<<endl;
        }
        else if(op==4) {
            cout<<A.queryjiang(1,l,r)<<endl;
        }
        else{
            int L=l+1,R=r-1;
            int ans=-1;
            int ma=A.querymax(1,l+1,r-1);
            while(L<=R){
                int mid=L+R>>1;
                if(A.querymax(1,l+1,mid)>=ma){
                    ans=mid;
                    R=mid-1;
                }
                else L=mid+1;
            }
            if(ans==-1){
                cout<<"0\n";
            }
            else{
                cout<<(A.querysheng(1,l,ans) and A.queryjiang(1,ans,r))<<endl;
            }
        }

    }
    return 0;
}