• 10.19NOIP模拟赛(DAY2)


    /*
    正解O(n)尺取法orz
    我写的二分答案。本来以为会被卡成暴力分......
    这个-'0'-48是我写的吗........我怎么不记得...
    */
    #include<bitsstdc++.h>
    
    #define N 1000001
    #define inf 0x3f3f3f3f
    
    using namespace std;
    int n,m,ans,cnt,flag;
    char s1[N],s2[N],cur[N];
    int vis[28][N],v[200];
    
    bool judge(int l,int len)
    {
        for(int i=1;i<=cnt;i++)
          if(vis[cur[i]-'0'-48][l+len-1]-vis[cur[i]-'0'-48][l-1]==0) return false;  
        return true;
    }
    
    int main()
    {
        freopen("english.in","r",stdin);
        freopen("english.out","w",stdout);
        scanf("%d",&n);
        scanf("%s",s1);
        for(int i=0;i<n;i++) vis[s1[i]-'0'-48][i]=1;
        for(int j='a';j<='z';j++) for(int i=1;i<=n;i++) 
        {
            if(s1[i]==j) vis[j-'0'-48][i]=vis[j-'0'-48][i-1]+1;
            else vis[j-'0'-48][i]=vis[j-'0'-48][i-1];
        }
        scanf("%s",s2);
        int len=strlen(s2);
        for(int i=0;i<len;i++)
          if(!v[s2[i]-'0'-48]) v[s2[i]-'0'-48]=1,cur[++cnt]=s2[i];
        for(int i=n-len;i<n;i++) if(s1[i]!=s2[i]) flag=1;
        if(!flag)
        {
            printf("%d
    ",len);
            return 0;
        } 
        int l,r,mid;ans=n;
        for(int i=1;i<=n-len;i++)
        {
            l=0,r=ans;
            while(l<=r)
            {
                int mid=(l+r)>>1;
                if(judge(i,mid)) ans=min(ans,mid),r=mid-1;
                else l=mid+1;
            }
            if(ans==len) break;
        }
        printf("%d
    ",ans);
        fclose(stdin);fclose(stdout);
        return 0;
    }

    /*
    首先如果数列最大最小差大于1是显然不行
    如果都为n-1显然可以
    其余情况嘛
    有n个人,A说,你们一群人中我看到了3种颜色。B说,我比你牛逼,我看到了四种!
    这说明了什么?想一想就能明白,说明颜色一定有4种,并且A头顶上的颜色一定跟所有人不同。
    因此所有较小的数都是一种与众不同的颜色,较大的数这个集合里肯定至少两两相同。
    */
    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    
    #define N 1000007
    
    using namespace std;
    int n,x,y,ans,cnt1,cnt2;
    int a[N];
    
    inline int read()
    {
        int x=0,f=1;char c=getchar();
        while(c>'9'||c<'0'){if(c=='-')f=-1;c=getchar();}
        while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();}
        return x*f;
    }
    
    int main()
    {
        freopen("hat.in","r",stdin);
        freopen("hat.out","w",stdout);
        int T;T=read();
        while(T--)
        {
            n=read();a[1]=read();cnt1=0;cnt2=0;
            x=0;y=0;
            for(int i=2;i<=n;i++)
            {
                a[i]=read();
                if(a[i]!=a[i-1]) x=a[i],y=a[i-1];
            }
            if(x==0 && y==0){printf("Yes
    ");continue;}
            if(x>y) swap(x,y);
            for(int i=1;i<=n;i++)
            {
                if(a[i]==x) cnt1++;
                if(a[i]==y) cnt2++;
            }
            if(cnt1+cnt2!=n)
            {
                printf("Yes
    ");
                continue;
            }
            if(cnt2==1) printf("Yes
    ");
            else if(cnt2/2>=y-cnt1) printf("No
    ");
            else printf("Yes
    ");
        }
        fclose(stdin);fclose(stdout);
        return 0;
    }

    /*
    严格次小生成树模板
    */
    #include<cstdio>
    #include<iostream>
    #include<cstring>
    #include<algorithm>
    
    #define Maxn 300010
    
    using namespace std;
    
    struct edge
    {
        int to,w,next;
    } p[Maxn];
    int head[Maxn/3],tot;
    void addedge(int a,int b,int c)
    {
        p[tot].to=b;
        p[tot].w=c;
        p[tot].next=head[a];
        head[a]=tot++;
    }
    
    struct line
    {
        int u,v,w;
        bool operator<(const line &a)const
        {
            return w<a.w;
        }
    } q[Maxn];
    
    int vis[Maxn];
    int fa[Maxn/3];
    
    int findset(int x)
    {
        return fa[x]==x?x:(fa[x]=findset(fa[x]));
    }
    
    int unionset(int a,int b)
    {
        return fa[findset(a)]=findset(b);
    }
    
    int dep[Maxn/3];
    int f[Maxn/3][20],g[Maxn/3][20],h[Maxn/3][20];
    void dfs(int u,int fa)
    {
        f[u][0]=fa;
        dep[u]=dep[fa]+1;
        for(int i=head[u]; i!=-1; i=p[i].next)
        {
            int v=p[i].to;
            if(v!=fa)
            {
                g[v][0]=p[i].w;
                h[v][0]=-1;
                dfs(v,u);
            }
        }
    }
    
    void ck1(int &a,int &b,int c,int d,int e,int f)
    {
        if(c==e)
        {
            a=c;
            b=max(d,f);
            return;
        }
        if(c>e)
        {
            swap(c,e); 
            swap(d,f);
        }
        a=e;
        b=max(c,f);
    }
    int ck2(int lx,int ln,int w)
    {
        if(w==lx) return w-ln; 
        return w-lx; 
    }
    void ck3(int &lx,int &ln,int u,int t)
    {
        if(g[u][t]==lx) ln=max(ln,h[u][t]);
        else if(g[u][t]<lx) ln=max(ln,g[u][t]);
        else
        {
            ln=(lx,h[u][t]);
            lx=g[u][t];
        }
    }
    void init(int n)
    {
        dfs(1,0);
        for(int j=0; j<18; j++)
            for(int i=1; i<=n; i++)
            {
                if(!f[i][j]) f[i][j+1]=0;
                else
                {
                    f[i][j+1]=f[f[i][j]][j];
                    ck1(g[i][j+1],h[i][j+1],g[i][j],h[i][j],g[f[i][j]][j],h[f[i][j]][j]);
                }
            }
    }
    int LCA(int u,int v,int w)
    {
        int lx=-1,ln=-1;
        if(dep[u]<dep[v]) swap(u,v);
        int df=dep[u]-dep[v],t=0;
        while(df)
        {
            if(df&1)
            {
                ck3(lx,ln,u,t);
                u=f[u][t];
            }
            t++;
            df>>=1;
        }
        if(u==v) return ck2(lx,ln,w);
        for(int i=18; i>=0; i--)
        {
            if(f[u][i]!=f[v][i])
            {
                ck3(lx,ln,u,i);
                ck3(lx,ln,v,i);
                u=f[u][i];
                v=f[v][i];
            }
        }
        ck3(lx,ln,u,0);
        ck3(lx,ln,v,0);
        return ck2(lx,ln,w);
    }
    int main()
    {
        freopen("tree.in","r",stdin);
        freopen("tree.out","w",stdout);
        int n,m;
        scanf("%d%d",&n,&m);
        for(int i=0; i<m; i++)
            scanf("%d%d%d",&q[i].u,&q[i].v,&q[i].w);
        sort(q,q+m);
        for(int i=1; i<=n; i++) fa[i]=i;
        memset(head,-1,sizeof head);
        memset(vis,0,sizeof vis);
        tot=0;
        int cnt=0;
        long long ans=0;
        for(int i=0; i<m; i++)
        {
            int u=q[i].u,v=q[i].v;
            if(findset(u)==findset(v)) continue;
            unionset(u,v);
            vis[i]=1;
            addedge(u,v,q[i].w);
            addedge(v,u,q[i].w);
            ans+=q[i].w;
            if(++cnt==n-1) break;
        }
        init(n);
        int z=0x3f3f3f3f;
        for(int i=0; i<m; i++)
            if(!vis[i]) z=min(z,LCA(q[i].u,q[i].v,q[i].w));
        cout<<ans+z<<endl;
        return 0;
    }
  • 相关阅读:
    idea 搭建spring boot
    面向对象
    idea 转普通项目为maven 项目
    java 基础
    设计模式
    GeneratedKeyHolder的作用:获得新建主键值
    Oracle中Merge into的用法实例讲解
    深入理解Java线程池:ThreadPoolExecutor
    java Timer(定时调用、实现固定时间执行)
    js实现数组去重
  • 原文地址:https://www.cnblogs.com/L-Memory/p/9818171.html
Copyright © 2020-2023  润新知