• GDKOI2021 PJ D1 题解


    这个普及比普及水多了。(雾)

    题目水到我 9:44 写完又对拍到 11:00 然后发现自己差劲的代码能力一遍AK?(并没有)

    所以总结就不写了

    考场本来有 Sublime ,结果想配一下自动补全的时候 C++ 包莫名其妙没了,于是只能当记事本用。

    本来用的 fread 快读,但是发现数据后都没有回车 fread 会双倍末尾,于是换成了 getchar

    这场比赛因为我清奇的脑回路变成了并查集专题。

    T1 map

    模拟水题。

    #include<cstdio>
    using namespace std;
    int n,a[2010][2010],r[2010],c[2010],x=1,y=1,ox,oy;
    template<typename T>void read(T &x){
        char c=getchar();
        for(;c<33;c=getchar());
        for(x=0;47<c&&c<58;x=(x<<3)+(x<<1)+(c^48),c=getchar());
    }
    int main(){
        freopen("map.in","r",stdin);
        freopen("map.out","w",stdout);
        read(n);
        for(int i=1;i<=n;++i){
            for(int j=1;j<=n;++j){
                read(a[i][j]);
            }
        }
        for(int i=2;i<n;++i){
            r[i]=a[n][1];
            c[i]=a[1][n];
            for(int j=2;j<=n;++j){
                r[i]^=a[i][j]^a[n][j];
                c[i]^=a[j][i]^a[j][n];
            }
        }
        for(int i=2;i<n;++i){
            if(r[i]!=a[i][1]){
                x=i;
                ++ox;
            }
            if(c[i]!=a[1][i]){
                y=i;
                ++oy;
            }
        }
        if(a[1][1]==1){
            printf("1 1");  //然现在发现并不需要
        }else{
            printf("%d %d",ox>1?n:x,oy>1?n:y);
        }
        fclose(stdin);
        fclose(stdout);
        return(0);
    }
    

    T2 water

    全场最有质量的题……?

    是 water !

    暗示我们比赛很水

    然后身边一群人写 (nlog ^2n) ,然后 (nlog n) 的方法也很神奇,甚至 Splay 、甚至 ST 表、甚至权值线段树……甚至再套二分……?反正我写的并查集。


    首先如果水越加越高,那么就会不断的使有水的区间变大。

    所以直接对询问由小到大排序,记录区间的左右端点,暴力拓展,用并查集合并即可。

    随便写写跑得飞快,然后写完 T4 把 T4 的 sz 数组 copy 了过来搞了个按秩合并。

    #include<cstdio>
    #include<algorithm>
    #define N 200010
    using namespace std;
    int n,m,c[N],sz[N];
    long long ans[N],a[N],s[N],l[N],r[N];
    struct ques{
        int x,y,num;
    }q[N];
    template<typename T>void read(T &x){
        char c=getchar();
        for(;c<33;c=getchar());
        for(x=0;47<c&&c<58;x=(x<<3)+(x<<1)+(c^48),c=getchar());
    }
    bool cmp(ques a,ques b){
        return(a.y<b.y);
    }
    int root(int x){
        if(c[x]){
            sz[c[x]]+=sz[x];
            sz[x]=0;
            return(c[x]=root(c[x]));
        }
        return(x);
    }
    int uni(int x,int y){
        x=root(x);y=root(y);
        if(sz[x]<sz[y]){
            swap(x,y);
        }
        if(x!=y){
            c[y]=x;
            sz[x]+=sz[y];
            sz[y]=0;
            l[x]=min(l[x],l[y]);
            r[x]=max(r[x],r[y]);
        }
        return(x);
    }
    int main(){
        freopen("water.in","r",stdin);
        freopen("water.out","w",stdout);
        read(n);read(m);
        for(int i=1;i<=n;++i){
            read(a[i]);
            s[i]=s[i-1]+a[i];
            l[i]=r[i]=i;
            sz[i]=1;
        }
        for(int i=1;i<=m;++i){
            read(q[i].x);read(q[i].y);q[i].num=i;
        }
        sort(q+1,q+1+m,cmp);
        for(int i=1;i<=m;++i){
            q[i].x=root(q[i].x);
            for(;a[l[q[i].x]-1]<q[i].y&&l[q[i].x]>1;q[i].x=uni(l[q[i].x]-1,q[i].x));
            for(;a[r[q[i].x]+1]<q[i].y&&r[q[i].x]<n;q[i].x=uni(r[q[i].x]+1,q[i].x));
            ans[q[i].num]=(r[q[i].x]-l[q[i].x]+1)*q[i].y-s[r[q[i].x]]+s[l[q[i].x]-1];
        }
        for(int i=1;i<=m;++i){
            printf("%lld
    ",ans[i]);
        }
        fclose(stdin);
        fclose(stdout);
        return(0);
    }
    

    T3 match

    甚至比 T1 好写,贪心显然。

    然后死于数组没开大。

    #include<cstdio>
    #include<algorithm>
    using namespace std;
    int n,l,r,a[100010],ans;  //我谔谔极了
    //int n,l,r,a[1000010],ans;
    template<typename T>void read(T &x){
        char c=getchar();
        for(;c<33;c=getchar());
        for(x=0;47<c&&c<58;x=(x<<3)+(x<<1)+(c^48),c=getchar());
    }
    int main(){
        freopen("match.in","r",stdin);
        freopen("match.out","w",stdout);
        read(n);read(l);read(r);
        for(int i=1;i<=n;++i){
            read(a[i]);
        }
        sort(a+1,a+n+1);
        for(int x=1,y=n;x<=y;){
            if(x==y){
                ++ans;
                break;
            }else if(a[x]+a[y]<l){
                ++x;
                ++ans;
            }else if(a[x]+a[y]>r){
                --y;
                ++ans;
            }else{
                ++x;
                --y;
            }
        }
        printf("%d",ans);
        fclose(stdin);
        fclose(stdout);
        return(0);
    }
    

    T4 travel

    考场上屡次打成 tarvel 了解一下?

    首先就是,这道题是原题: USACO2018JanGold P1. MooTube

    除了多了若干条边以外并没有任何区别。

    离线排序并查集。

    就跟T2一样

    #include<cstdio>
    #include<algorithm>
    #define N 200010
    using namespace std;
    int n,m,k,s[N],sz[N],ans[N];
    struct edge{
        int x,y,c;
    }e[N<<3],q[N<<3];
    template<typename T>void read(T &x){
        char c=getchar();
        for(;c<33;c=getchar());
        for(x=0;47<c&&c<58;x=(x<<3)+(x<<1)+(c^48),c=getchar());
    }
    bool cmp(edge a,edge b){
        return(a.c<b.c);
    }
    void pushup(int x){
        sz[s[x]]+=sz[x];
        sz[x]=0;
    }
    int root(int x){
        if(s[x]){
            pushup(x);
            return(s[x]=root(s[x]));
        }
        return(x);
    }
    int uni(int x,int y){
        x=root(x);y=root(y);
        if(sz[x]<sz[y]){
            swap(x,y);
        }
        if(x!=y){
            s[y]=x;
            pushup(y);
        }
        return(x);
    }
    int main(){
        freopen("travel.in","r",stdin);
        freopen("travel.out","w",stdout);
        read(n);read(m);
        for(int i=1;i<=n;++i){
            sz[i]=1;
        }
        for(int i=0;i<m;++i){
            read(e[i].x);read(e[i].y);read(e[i].c);
        }
        read(k);
        for(int i=0;i<k;++i){
            read(q[i].x);read(q[i].c);q[i].y=i;
        }
        sort(e,e+m,cmp);
        sort(q,q+k,cmp);
        for(int i=0,j=0;i<k;++i){
            for(;j<=m&&e[j].c<=q[i].c;uni(e[j].x,e[j].y),++j);
            ans[q[i].y]=sz[root(q[i].x)];
        }
        for(int i=0;i<k;++i){
            printf("%d
    ",ans[i]);
        }
        fclose(stdin);
        fclose(stdout);
        return(0);
    }
    
  • 相关阅读:
    nyoj58 最少步数
    oj2787 算24
    一位ACMer过来人的心得
    hdu递推公式水题
    nyoj20 吝啬的国度
    hdu1421 搬寝室
    全排列生成算法:next_permutation
    hdu2544 最短路
    poj1691 Painting A Board
    hdu1274 展开字符串
  • 原文地址:https://www.cnblogs.com/groundwater/p/14332383.html
Copyright © 2020-2023  润新知