• 四连测Day1


    题目:链接: https://pan.baidu.com/s/163ycV64ioy7uML7AvRDTGw 密码: p86i

    T1:

    倍增求LCA,minn数组记录最小值

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<cmath>
    using namespace std;
    inline long long read()
    {
        long long f=1,ans=0;char c;
        while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
        while(c>='0'&&c<='9'){ans=ans*10+c-'0';c=getchar();}
        return ans*f;
    }
    long long q,a[500001],fa[500001][23],minn[500001][23];
    struct node{
        long long x;long long y;
        long long nex;
    }ss[1000001];
    long long head[500001];
    long long cnt=1;
    void add(long long a,long long b)
    {
        ss[cnt].x=a,ss[cnt].y=b;
        ss[cnt].nex=head[a],head[a]=cnt++;
        return;
    }
    long long deep[500001];
    void dfs(long long f,long long fath)
    {
        deep[f]=deep[fath]+1;
        minn[f][0]=min(a[f],a[fath]);
        fa[f][0]=fath;
        for(long long i=1;(1<<i)<=deep[f];i++) fa[f][i]=fa[fa[f][i-1]][i-1],minn[f][i]=min(minn[f][i-1],minn[fa[f][i-1]][i-1]);
        for(long long i=head[f];i!=-1;i=ss[i].nex)
            if(ss[i].y!=fath) dfs(ss[i].y,f);
    }
    long long n,m,s;
    long long lca(long long u,long long v)
    {
        long long sry=min(a[u],a[v]);
    //    cout<<sry<<endl;
        if(deep[u]<deep[v]) swap(u,v);
        for(long long i=22;i>=0;i--)
            if(deep[u]-(1<<i)>=deep[v]) sry=min(sry,minn[u][i]),u=fa[u][i];
    //        cout<<sry<<" "<<u<<" "<<v<<endl; 
        if(u==v) return sry;
        for(long long i=22;i>=0;i--)
        {
            if(fa[u][i]==fa[v][i]) continue;
            else 
            {
                sry=min(sry,minn[u][i]),sry=min(sry,minn[v][i]);
                u=fa[u][i],v=fa[v][i];
            }
        }
    //    cout<<fa[u][0]<<endl;
        return min(sry,a[fa[u][0]]);
    }
    int main()
    {
        memset(head,-1,sizeof(head));
        n=read(),q=read();
        for(long long i=1;i<=n;i++) a[i]=read();
        for(long long i=1;i<n;i++)
        {
            long long u=read(),v=read();
            add(u,v),add(v,u);
        }
        dfs(1,0);
        for(long long i=1;i<=q;i++)
        {
            long long u=read(),v=read();
            printf("%d
    ",lca(u,v));
    //        return 0;
        }
    }/*
    5 5
    8 100 502 9 3
    2 4
    4 1
    1 3
    1 5
    3 5
    1 5
    2 3
    2 1
    3 4
    */
    View Code

    T2:

    桶排序,因为告诉你a[i]最大为1048575,异或和为a[i]^a[i+1]^……a[j],拿sort会超时

    #include<iostream>
    #include<algorithm>
    #include<cmath>
    #include<cstring>
    #include<cstdio>
    using namespace std;
    inline int read()
    {
        int f=1,ans=0;char c;
        while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
        while(c>='0'&&c<='9'){ans=ans*10+c-'0';c=getchar();}
        return f*ans;
    }
    int a[1048576],x[50005001];
    int n,s[10001];
    int main()
    {
        n=read();int q=read();
        for(int i=1;i<=n;i++) s[i]=read();
        for(int i=1;i<=n;i++)
        {
            int sum=0;
            for(int j=i;j<=n;j++) sum^=s[j],a[sum]++;
        }
        int cnt=0;
        for(int i=0;i<=1048575;i++) 
            while(a[i]!=0) x[++cnt]=i,a[i]--;
        for(int i=1;i<=q;i++) 
        {
            int xx=read();
            printf("%d
    ",x[xx]);
        }
    }
    View Code

    T3:

    先将每一个点想成一个区间,r[i]表示i的祖先节点所在区间的最右号,l同理,f为祖先,j=r[find(j)]+1表示因为j号节点的区间右侧为r[find(j)],所以可得。

    将边权从小到大排序,区间覆盖即可

    #include<iostream>
    #include<algorithm>
    #include<cmath>
    #include<cstring>
    #include<cstdio>
    using namespace std;
    inline int read()
    {
        int f=1,ans=0;char c;
        while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
        while(c>='0'&&c<='9'){ans=ans*10+c-'0';c=getchar();}
        return f*ans;
    }
    int n,m;
    int f[100001],r[100001],l[100001];
    int find(int x)
    {
        if(f[x]==x) return x;
        return f[x]=find(f[x]);
    }
    struct node{
        int ll,rr,v;
    }x[100001];
    bool cmp(node xx,node yy)
    {
        return xx.v<yy.v;
    }
    int ans,sum;
    void merge(int x1,int x2)
    {
        int t1=find(x1),t2=find(x2);
        f[t2]=t1;
        l[t1]=min(l[t1],l[t2]);
        r[t1]=max(r[t1],r[t2]);
    }
    int main()
    {
        n=read(),m=read();
        for(int i=1;i<=n;i++) f[i]=l[i]=r[i]=i;
        for(int i=1;i<=m;i++)  x[i].ll=read(),x[i].rr=read(),x[i].v=read();
        sort(x+1,x+m+1,cmp);
        for(int i=1;i<=m;i++)
        {
            int j=r[find(x[i].ll)]+1;
            while(j<=x[i].rr)
            {
                ans++;
                sum+=x[i].v;
                merge(x[i].ll,j);
                j=r[find(j)]+1;
            }
            if(ans==n-1) 
            {
                printf("%d
    ",sum);
                return 0;
            }
        }
        cout<<-1;
    }
    /*
    5 4
    1 2 1
    3 4 2
    3 5 3
    1 4 1
    */
    View Code
  • 相关阅读:
    el-checkbox
    文件上传优化
    二叉树的建立
    二叉树的遍历算法
    两个二进制数多少个位(bit)不同
    二维矩阵置零
    search-a-2d-matrix(二维矩阵查找)
    Ubuntu16.04安装配置Eclipse 以及opencv的使用
    树莓派 自身摄像头的opencv调用
    树莓派3上安装Qt5
  • 原文地址:https://www.cnblogs.com/si-rui-yang/p/9452332.html
Copyright © 2020-2023  润新知