9.30数据结构模拟赛

来源:互联网 发布:网络监控器怎么安装 编辑:程序博客网 时间:2024/06/03 10:48

大意的后果:290分->40分
小小总结一下:
1.并查集按秩合并不要敲太快,不然不知不觉打上去个路径压缩就GG了。
2.把暴力程序的数组复制到正解程序的数组时一定要检查数组开没开够,毕竟暴力是针对30%的数据。。。
3.map等STL的具体用法要搞清楚。

这里写图片描述
题解:并查集按秩合并,然后查一下dep即可。

#include<cstdio>#include<cstring>#include<iostream>#include<algorithm>#include<map>using namespace std;const int MAXN=1e5+4;int n,m,a,b;int fa[MAXN],rk[MAXN],w[MAXN],dep[MAXN],tim=0;map<int ,int > mp;int tot=0;int find(int x) {    return fa[x]==x?x:/*fa[x]=*/find(fa[x]);//233......}inline void merge(int x,int y) {    if (rk[x]>rk[y]) x^=y^=x^=y;    fa[x]=y;    w[x]=++tim;    if (rk[x]==rk[y]) ++rk[y];}void dfs(int u) {    if (fa[u]==u) return ;    dfs(fa[u]);    dep[u]=dep[fa[u]]+1;}inline int query(int u,int v) {    int ret=0;    dfs(u),dfs(v);    if (dep[u]<dep[v]) u^=v^=u^=v;    while (dep[u]>dep[v]&&u^v) {        ret=max(ret,w[u]);        u=fa[u];    }    while(u^v) {        ret=max(ret,max(w[u],w[v]));        u=fa[u],v=fa[v];    }    return ret;}int main() {    freopen("union.in","r",stdin);    freopen("union.out","w",stdout);    mp.clear();    scanf("%d%d",&n,&m);    for (register int i=1;i<=n;++i) fa[i]=i;    for (register int i=1;i<n;++i) {        scanf("%d%d",&a,&b);        if (!mp.count(a)) mp[a]=++tot,a=tot;        else a=mp[a];        if (!mp.count(b)) mp[b]=++tot,b=tot;        else b=mp[b];        merge(find(a),find(b));    }    for (register int CR7=0;CR7<m;++CR7) {        scanf("%d%d",&a,&b);        printf("%d\n",query(mp[a],mp[b]));    }    return 0;}

这里写图片描述
题解:将LCS转成LIS
(1) 对序列B排序
(2) 计算A中每个元素在B中的序号,并构成新序列
(3) 使用LIS的方法计算最长严格递增子序列
(4) 获取最长公共子序列
也可以用树状数组。
复杂度O(nlogn)

#include<cstdio>#include<cstring>#include<iostream>#include<algorithm>using namespace std;const int MAXN=1e5+4,INF=0x3f3f3f3f;int n,a[MAXN],c[MAXN],sta[MAXN];struct B {    int id,v;    friend bool operator <(const B &x,const B &y) {        return x.v<y.v;    }}b[MAXN];inline int read() {    int x=0,f=1;char c=getchar();    while (c<'0'||c>'9') {if (c=='-') f=-1;c=getchar();}    while (c>='0'&&c<='9') x=x*10+c-'0',c=getchar();    return x*f;}int main() {    freopen("lcs.in","r",stdin);    freopen("lcs.out","w",stdout);    n=read();    for (register int i=1;i<=n;++i) a[i]=read();    for (register int i=1;i<=n;++i) b[i].v=read(),b[i].id=i;    sort(b+1,b+n+1);    for (register int i=1;i<=n;++i) c[i]=b[a[i]].id;    //LIS    int len=0,j;    sta[0]=-INF;    for (int i=1;i<=n;i++) {        if (c[i]>sta[len]) j=++len;        else j=upper_bound(sta+1,sta+len+1,c[i])-sta;        sta[j]=c[i];    }    printf("%d\n",len);    return 0;}

这里写图片描述
题解:map乱搞即可,也可以邻接表建图。

#include<cstdio>#include<cstring>#include<string>#include<iostream>#include<algorithm>#include<map>using namespace std;//<D>==1,<F>==2#define mkp(x,y) make_pair(x,y)const int MAXN=105;int n;map<pair <string ,int >,int > mp[MAXN];int tim=1,cur,fa[MAXN];string nam[MAXN];int type[MAXN];int main() {    freopen("files.in","r",stdin);    freopen("files.out","w",stdout);    memset(fa,0,sizeof(fa));    scanf("%d",&n);    for (int i=1;i<=n;++i) mp[i].clear();    cur=1;    for (int i=1;i<=n;++i) {        char ss[1002],tt[1002];        scanf("%s",ss);        if (ss[0]=='c'&&ss[1]=='d') {            scanf("%s",tt);            if (tt[0]^'.') {                if (mp[cur].count(mkp(tt,1))) cur=mp[cur][mkp(tt,1)];//mp[cur].count(mkp(tt,1))不等于mp[cur][mkp(tt,1)]!!!!!!!!                else puts("No such directory!");            }            else {                if (fa[cur]) cur=fa[cur];                else puts("No parent directory!");            }        }        else if (ss[0]=='t') {//创建文件            scanf("%s",tt);            if (!mp[cur].count(mkp(tt,2)))                mp[cur][mkp(tt,2)]=++tim,nam[tim]=tt,type[tim]=2,fa[tim]=cur;            else puts("File already exists!");        }        else if (ss[0]=='m') {//创建文件夹             scanf("%s",tt);            if (!mp[cur].count(mkp(tt,1)))                mp[cur][mkp(tt,1)]=++tim,nam[tim]=tt,type[tim]=1,fa[tim]=cur;            else puts("Directory already exists!");        }        else if (ss[0]=='r'&&ss[2]=='\0') {//删除文件            scanf("%s",tt);            if (!mp[cur].count(mkp(tt,2))) puts("No such file!");            else {                int temp=mp[cur][mkp(tt,2)];                mp[cur].erase(mkp(tt,2)),type[temp]=fa[temp]=0;            }        }        else if (ss[0]=='r'&&ss[2]^'\0') {//删除文件夹            scanf("%s",tt);            if (!mp[cur].count(mkp(tt,1))) puts("No such directory!");            else {                int temp=mp[cur][mkp(tt,1)];                mp[cur].erase(mkp(tt,1)),type[temp]=fa[temp]=0;            }        }        else if (ss[0]=='l') {//输出//          puts("  LIST_ST:");            for (int i=1;i<=tim;++i) {                if (type[i]==1&&fa[i]==cur) cout<<nam[i]<<' '<<"<D>\n";                else if (type[i]==2&&fa[i]==cur) cout<<nam[i]<<' '<<"<F>\n";            }//          puts("  LIST_ED:");        }    }    return 0;}