zoukankan      html  css  js  c++  java
  • 数据结构1

    集合合并

    有n个元素,每个元素在不同的集合内,给出n-1个操作合并两个元素所在集合,保证之前不在同一集合。

    有m个询问,(x,y)是在第几次操作后第一次位于同一集合。

    n<=1e5

    题解

    操作完之后就是一棵树,任意两点间只有一条简单路径,只要路径上的边都建好就联通,所以就是查路径最大值,边权为是第几次操作。

    那么用倍增维护就好了,注意细节。

    #include<cstdio>
    #include<iostream>
    #include<algorithm>
    using namespace std;
    
    const int maxn=200005;
    int n,m;
    int dep[maxn],fa[maxn][25],mx[maxn][25];//mx:从i到走2^j步到达的点的路径最大值 
    int cnt,head[maxn];
    struct edge{
        int x,y,val,next;
    }e[maxn<<1];
    
    template<class T>inline void read(T &x){
        x=0;int f=0;char ch=getchar();
        while(!isdigit(ch)) {f|=(ch=='-');ch=getchar();}
        while(isdigit(ch)) {x=(x<<1)+(x<<3)+(ch^48);ch=getchar();}
        x= f ? -x : x ;
    }
    
    void add(int x,int y,int val){
        e[++cnt]=(edge){x,y,val,head[x]};
        head[x]=cnt;
    }
    
    void dfs(int x){
        for(int i=head[x];i;i=e[i].next){
            int y=e[i].y;
            if(y==fa[x][0]) continue;
            dep[y]=dep[x]+1;
            fa[y][0]=x;
            mx[y][0]=e[i].val;
            dfs(y);
        }
    }
    
    void rmq(){
        for(int j=1;j<=20;j++)
         for(int i=1;i<=n;i++){
              fa[i][j]=fa[fa[i][j-1]][j-1];
              mx[i][j]=max(mx[i][j-1],mx[fa[i][j-1]][j-1]);
         }
    }
    
    int query(int x,int y){
        if(dep[x]<dep[y]) swap(x,y);
        int delt=dep[x]-dep[y];
        int ret=0;
        for(int i=0;delt;i++,delt>>=1)
         if(delt&1){
              ret=max(ret,mx[x][i]);
              x=fa[x][i];
         }
        if(x==y) return ret;
        for(int i=20;fa[x][0]!=fa[y][0];i--)
         if(fa[x][i]!=fa[y][i]){
              ret=max(ret,mx[x][i]);
              ret=max(ret,mx[y][i]);
              x=fa[x][i];
              y=fa[y][i];
         }
        return max(ret,max(mx[x][0],mx[y][0]));
    }
    
    int main(){
        freopen("union.in","r",stdin);
        freopen("union.out","w",stdout);
        read(n);read(m);
        for(int i=1;i<n;i++){
            int x,y;read(x);read(y);
            add(x,y,i);
            add(y,x,i);
        }
        dfs(1);
        rmq();
        for(int i=1;i<=m;i++){
            int x,y;
            read(x);read(y);
            printf("%d
    ",query(x,y));
        }
    }
    union

    最长公共子序列

    给出两个长度为n的排列,求最长公共子序列。

    题解

    模板题,将a数组映射到b数组,那么b数组就变成了每个数在a数组中的下标。

    然后求lis即可。

    维护f数组:长度为i的上升子序列末尾最小是f[i],这个数组是单增的(假设f[i]>f[j]&&i<j,但是长度为j的上升子序列中,选取前i个数,第i个数<f[j]<f[i],不满足定义)

    按顺序搞b数组,对于b[i]找f数组中最大的j使得b[i]>f[j],然后组成一个长度为j+1的上升子序列,f[j+1]=b[i](不存在原来的f[j+1]<b[i],不然找到的就是j+1),二分查找

    最后看f数组中最大的不为最大值的位置。

    注意a和b,还有在二分里面传入的是b[i]的话,就不要写b[x](我写成了a[x]可还行)

    #include<cstdio>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    using namespace std;
    
    const int maxn=100005;
    int n;
    int a[maxn],mp[maxn],b[maxn],f[maxn];
    
    template<class T>inline void read(T &x){
        x=0;int f=0;char ch=getchar();
        while(!isdigit(ch)) {f|=(ch=='-');ch=getchar();}
        while(isdigit(ch)) {x=(x<<1)+(x<<3)+(ch^48);ch=getchar();}
        x= f ? -x : x ;
    }
    
    int find(int x){
        int l=0,r=n,ans=0;
        while(l<=r){
            int mid=(l+r)>>1;
            if(x>f[mid]) ans=mid,l=mid+1;
            else r=mid-1;
        }
        return ans;
    }
    
    int main(){
        freopen("lcs.in","r",stdin);
        freopen("lcs.out","w",stdout);
        read(n);
        for(int i=1;i<=n;i++){
            read(a[i]);
            mp[a[i]]=i;
        }
        for(int i=1;i<=n;i++){
            read(b[i]);
            b[i]=mp[b[i]];
        }
        for(int i=1;i<=n;i++) f[i]=0x3f3f3f;
        for(int i=1;i<=n;i++){
            int x=find(b[i]);
            f[x+1]=b[i];
        }
        for(int i=n;i;i--)
         if(f[i]!=0x3f3f3f){
              printf("%d",i);
              return 0;
         }
    }
    lcs

    文件系统

    就是模拟创建文件和文件夹,删除文件和文件夹,返回上一级,输出这一级的文件和文件夹。

    用map模拟即可,一开始写的map<string,int>,结果错了,就改成了hash,结果是建文件夹写成了==。

    然后文件也是这么写的(没发现)

    #include<bits/stdc++.h>
    using namespace std;
    #define ull unsigned long long
    const int maxn=505;
    const ull base=10007;
    int q,cnt,now;
    char c[15];
    string ch;
    struct node{
        int id,belong;
        bool operator < (const node a) const {return a.id<id;}
    };
    struct point{
        int fa;
        map<ull,int> son[2];//0:文件 1:文件夹 
        map<int,string> mp[2];
        vector<node> s[2];
    }tr[maxn];
    
    ull get(){
        ull ret=0;
        int len=ch.size();
        for(int i=0;i<len;i++) ret=ret*base+ch[i];
        return ret;
    }
    
    void print(){
        priority_queue<node> q,no;
        for(unsigned int i=0;i<tr[now].s[0].size();i++) q.push(tr[now].s[0][i]);
        for(unsigned int i=0;i<tr[now].s[1].size();i++) no.push(tr[now].s[1][i]);
        while(!q.empty()){
            while(!no.empty()&&q.top().id==no.top().id) {q.pop();no.pop();}
            node x=q.top();
            q.pop();
            cout<<tr[now].mp[x.belong][x.id]<<" ";
            if(x.belong) cout<<"<D>";
            else cout<<"<F>";
            putchar(10);
        }
    }
    
    int main(){
        freopen("files.in","r",stdin);
        freopen("files.out","w",stdout);
        now=++cnt;
        scanf("%d",&q);
        while(q--){
            scanf("%s",c);
            if(c[0]=='l') {print();continue;}
            cin>>ch;
            ull val=get();
            if(c[0]=='c'){
                if(ch[0]=='.'){//退出 
                    if(!tr[now].fa) printf("No parent directory!
    ");
                    else now=tr[now].fa;
                }
                else {//进入 
                    if(tr[now].son[1][val]) now=tr[now].son[1][val];
                    else printf("No such directory!
    ");
                }
            }
            else if(c[0]=='t'){//创建文件 
                if(tr[now].son[0][val]) printf("File already exists!
    ");
                else {
                    tr[now].son[0][val]=++cnt;
                    tr[now].mp[0][cnt]=ch;
                    tr[now].s[0].push_back((node){cnt,0});
                }
            }
            else if(c[0]=='r'){
                if(strlen(c)==2) {//删除文件 
                    if(!tr[now].son[0][val]) printf("No such file!
    ");
                    else {
                        int x=tr[now].son[0][val];
                        tr[now].son[0][val]=0;
                        tr[now].s[1].push_back((node){x,0});
                    }
                }
                else {//删除文件夹 
                    if(!tr[now].son[1][val]) printf("No such directory!
    ");
                    else {
                        int x=tr[now].son[1][val];
                        tr[now].son[1][val]=0;
                        tr[now].s[1].push_back((node){x,1});
                    }
                }
            }
            else if(c[0]=='m'){//创建文件夹 
                if(tr[now].son[1][val]) printf("Directory already exists!
    ");
                else {
                    tr[now].son[1][val]=++cnt;
                    tr[cnt].fa=now;
                    tr[now].mp[1][cnt]=ch;
                    tr[now].s[0].push_back((node){cnt,1});
                }
            }
        }
    }
    /*
    3
    mkdir standy
    touch totalfrank
    ls
    */
    files
  • 相关阅读:
    17.1.2.1 Advantages and Disadvantages of Statement-Based and Row-Based Replication
    17.1.2 Replication Formats
    Setting the Master Configuration on the Slave
    17.1.1.9 Introducing Additional Slaves to an Existing Replication Environment
    17.1.1.8 Setting Up Replication with Existing Data
    17.1.1.7 Setting Up Replication with New Master and Slaves
    17.1.1.6 Creating a Data Snapshot Using Raw Data Files
    列出display的值,并说明它们的作用
    CSS设置DIV居中
    CSS选择符有哪些?哪些属性可以继承?优先级算法如何计算?
  • 原文地址:https://www.cnblogs.com/sto324/p/11580004.html
Copyright © 2011-2022 走看看