数据结构测试1 on 2019.9.24

Posted ljb666

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了数据结构测试1 on 2019.9.24相关的知识,希望对你有一定的参考价值。

T1 union

技术图片

 

 一开始我被这个题目带进去了,以为真的是并查集,但实际上此题与并查集毫无半毛钱关系。

其实我们可以先离线建好所有的图,然后把建边的时间作为他们的边权。因为两个点什么时候联通取决于它们路径上的点最晚的链接时间,也就是最大边权。而题目明摆了是一棵树,所有考虑树剖维护边权和查询最大值。

代码如下:

技术图片
#include<bits/stdc++.h>
using namespace std;
const int maxn=1e6+7;
struct node
    int nxt,to,val;
edge[maxn*3];
int head[maxn],cnt;
int n,m,x,y;
int w[maxn],dep[maxn],fa[maxn],size[maxn],son[maxn];
void add(int x,int y,int v)
    edge[++cnt].nxt=head[x];
    edge[cnt].to=y;
    edge[cnt].val=v;
    head[x]=cnt;

void dfs1(int x,int f)
    size[x]=1;
    fa[x]=f;
    dep[x]=dep[f]+1;
    int maxson=-1;
    for(int i=head[x];i;i=edge[i].nxt)
        int v=edge[i].to;
        if(v==fa[x]) continue;
        w[v]=edge[i].val;
        dfs1(v,x);
        size[x]+=size[v];
        if(size[v]>maxson)
            maxson=size[v];
            son[x]=v;
        
    

int top[maxn],id[maxn],in;
int val[maxn];
void dfs2(int x,int topf)
    top[x]=topf;
    id[x]=++in;
    val[id[x]]=w[x];
    if(!son[x]) return;
    dfs2(son[x],topf);
    for(int i=head[x];i;i=edge[i].nxt)
        int v=edge[i].to;
        if(v==fa[x]||v==son[x]) continue;
        dfs2(v,v);
    

struct node2
    int l,r,mx;
tree[maxn*4];
void build(int now,int l,int r)
    tree[now].l=l,tree[now].r=r;
    if(l==r)
        tree[now].mx=val[l];
        return;
    
    int mid=(l+r)>>1;
    build(now<<1,l,mid);
    build(now<<1|1,mid+1,r);
    tree[now].mx=max(tree[now<<1].mx,tree[now<<1|1].mx);

int query(int now,int l,int r)
    if(tree[now].l>=l&&tree[now].r<=r) return tree[now].mx;
    int ans=0;
    int mid=(tree[now].l+tree[now].r)>>1;
    if(l<=mid) ans=max(ans,query(now<<1,l,r));
    if(r>mid) ans=max(ans,query(now<<1|1,l,r));
    return ans;

int link(int x,int y)
    if(x==y) return 0;
    int ans=0;
    while(top[x]!=top[y])
        if(dep[top[x]]<dep[top[y]]) swap(x,y);
        ans=max(ans,query(1,id[top[x]],id[x]));
        x=fa[top[x]];
    
    if(dep[x]<dep[y]) swap(x,y);
    ans=max(ans,query(1,id[y]+1,id[x]));
    return ans;

int main()
    freopen("union.in","r",stdin);
    freopen("union.out","w",stdout); 
    scanf("%d%d",&n,&m);
    for(int i=1;i<n;i++)
        scanf("%d%d",&x,&y);
        add(x,y,i);add(y,x,i);
        
    dfs1(1,0);
    dfs2(1,1);
    build(1,1,n);
    for(int i=1;i<=m;i++)
        scanf("%d%d",&x,&y);
        printf("%d\\n",link(x,y));
    
    return 0;
 
View Code

T2 lcs

技术图片

题目非常显然,但是1e5的数据范围肯定没法像原来那样n方的去dp,于是我们必须将它用某种数据结构维护来优化为log的复杂度,显然想到树状数组。其实树状数组求lcs简单好写,跑的还非常快。

树状数组都知道可以求lis,但怎么把它转化为求lcs的问题呢?肯定是离散化啊!先将第一个序列离散为一个单调递增的序列,然后根据第一个序列上每一位的哈希值又离散化第二个序列,这个时候我们发现,由于第一个序列已经是有序的了,我们将第二个序列离散化后最长单调递增的序列那么肯定就是lcs了。

技术图片
//离散化,转化为树状数组求lis的问题 
#include<bits/stdc++.h>
using namespace std;
const int maxn=1e5+7;
int dp[maxn];
int n;
int a[maxn];
int c[maxn];
int b[maxn];
int lis[maxn];
int lis1[maxn];
int lowbit(int x)
    return x&(-x);

void modify(int x,int v)
    while(x<=n)
        c[x]=max(c[x],v);
        x+=lowbit(x);
    

int query(int x)
    int ans=0;
    while(x)
        ans=max(ans,c[x]);
        x-=lowbit(x);
    
    return ans;

int ans;
int main()
    scanf("%d",&n);
    for(int i=1;i<=n;i++)
        scanf("%d",&a[i]);
        lis[a[i]]=i;//映射,离散化 
     
    for(int i=1;i<=n;i++)
        scanf("%d",&b[i]);
        lis1[i]=lis[b[i]];
     
    for(int i=1;i<=n;i++)
        dp[i]=query(lis1[i])+1;
        modify(lis1[i],dp[i]);
    
    for(int i=1;i<=n;i++) ans=max(dp[i],ans);
    printf("%d\\n",ans);
    return 0;
 
View Code

T3 files

技术图片

 

 技术图片

stl+模拟文件操作即可

以上是关于数据结构测试1 on 2019.9.24的主要内容,如果未能解决你的问题,请参考以下文章

2019.9.24 网络ip小知识

数据结构测试2 on 2019.9.25

ruby on rails(测试用例指定创建数据库表)

求职作业帮 C++方向面经

spark on alluxio和MR on alluxio测试(改进版)

PostgreSQL on Azure.cn : 性能测试及调优