• 考试题目——雪后村庄


    题目描述
    这里写图片描述

    输入
    这里写图片描述

    输出
    输出q行,每行一个字符串“yes”或“no”(不包括引号)。

    样例输入
    Copy (如果复制到控制台无换行,可以先粘贴到文本编辑器,再复制)

    2 4
    3 4
    1 2 3
    2 3 2
    2 4 4
    1 2 3
    1 3 2
    2 3 2
    3 4 4
    4
    1 3 3
    1 3 2
    1 4 3
    3 4 4
    样例输出
    no
    yes
    no
    no
    提示
    这里写图片描述

    如果按着他的输入来做的话,你就炸了

    由于每个车夫(lao si ji)的能力(fan che)值,只与某些路径中最小的那一段比较,还不需要保存,倍增和LCA来做铁定超时

    这么多解决树上问题的姿势,为什么非要用这一种呢,并查集不也是解决这个问题很好的做法吗,将所有的边按边长从大到小排序,并将车夫(lao si ji)的能力(fan che)值从大到小排序,当某一次要处理的边小于了目前访问到的车夫(lao si ji)的能力(fan che)值,就先将这个车夫(lao si ji)的问题解决

    时间复杂度:O(qn),瞬间爆炸

    这个n能不能优化掉呢?
    yy到了哈希

    将某一户人家,它在每个村子里的并查集编号,用哈希从一位数组压缩到一个整数

    例:第i户人家,它在第j个村庄的并查集编号为x
    hash[i]+=xmaxnj

    由于maxnj太大,可将它模一个质数,如998244353

    但有时候模下来会有重复,则使用双哈希,同一个哈希模另一个质数,如1e9+7

    双哈希在NOIP中几乎无敌,不会有丧心病狂的卡双哈希的数据的

    头一次写双哈希,WA了十几次,QwQ
    AC代码如下:

    #include<cstdio>
    #include<cstring>
    #include<cmath>
    #include<algorithm>
    
    #define mod1 998244353
    #define mod2 1000000007
    #define maxn 200000
    #define maxr 300000
    
    using namespace std;
    
    inline long long getint()
    {
        long long num=0,flag=1;char c;
        while((c=getchar())<'0'||c>'9')if(c=='-')flag=-1;
        while(c>='0'&&c<='9')num=num*10+c-48,c=getchar();
        return num*flag;
    }
    
    struct node{
        long long u,v,w,bl;
    }road[maxr+5],dri[maxn+5];
    
    inline bool cmp(node x,node y){return x.w>y.w;}
    
    long long n,m,q,rd[maxn+5];
    long long hash1[maxn+5],hash2[maxn+5],ksm1[maxn+5],ksm2[maxn+5];
    long long fir[maxn+5],nxt[2*maxr+5],to[2*maxr+5],cnt;
    long long f[maxn+5],sum[maxn+5],siz[maxn+5];
    bool ans[maxn+5];
    
    inline void dfs(long long x,long long ch,long long ne)
    {
        for(long long i=fir[x];i;i=nxt[i])
            if(f[to[i]]==ne)
            {
                hash1[(to[i]-1)%m+1]=((hash1[(to[i]-1)%m+1]-(ne*ksm1[(to[i]-1)/m+1])%mod1)%mod1+mod1)%mod1;
                hash1[(to[i]-1)%m+1]=(hash1[(to[i]-1)%m+1]+(ch*ksm1[(to[i]-1)/m+1])%mod1)%mod1;
                hash2[(to[i]-1)%m+1]=((hash2[(to[i]-1)%m+1]-(ne*ksm2[(to[i]-1)/m+1])%mod2)%mod2+mod2)%mod2;
                hash2[(to[i]-1)%m+1]=(hash2[(to[i]-1)%m+1]+(ch*ksm2[(to[i]-1)/m+1])%mod2)%mod2;
                f[to[i]]=ch,siz[ch]++,siz[ne]--;
                dfs(to[i],ch,ne);
            }
    }
    
    inline void work(long long i)
    {
        long long u=road[i].u,v=road[i].v;
        if(siz[f[u]]>=siz[f[v]])
        {
            hash1[(v-1)%m+1]=((hash1[(v-1)%m+1]-(f[v]*ksm1[(v-1)/m+1])%mod1)%mod1+mod1)%mod1;
            hash1[(v-1)%m+1]=(hash1[(v-1)%m+1]+(f[u]*ksm1[(v-1)/m+1])%mod1)%mod1;
            hash2[(v-1)%m+1]=((hash2[(v-1)%m+1]-(f[v]*ksm2[(v-1)/m+1])%mod2)%mod2+mod2)%mod2;
            hash2[(v-1)%m+1]=(hash2[(v-1)%m+1]+(f[u]*ksm2[(v-1)/m+1])%mod2)%mod2;
            long long hh=f[v];f[v]=f[u];dfs(v,f[u],hh);
            siz[hh]--,siz[f[u]]++;
        }
        else
        {
            hash1[(u-1)%m+1]=((hash1[(u-1)%m+1]-(f[u]*ksm1[(u-1)/m+1])%mod1)%mod1+mod1)%mod1;
            hash1[(u-1)%m+1]=(hash1[(u-1)%m+1]+(f[v]*ksm1[(u-1)/m+1])%mod1)%mod1;
            hash2[(u-1)%m+1]=((hash2[(u-1)%m+1]-(f[u]*ksm2[(u-1)/m+1])%mod2)%mod2+mod2)%mod2;
            hash2[(u-1)%m+1]=(hash2[(u-1)%m+1]+(f[v]*ksm2[(u-1)/m+1])%mod2)%mod2;
            long long hh=f[u];f[u]=f[v];dfs(u,f[v],hh);
            siz[hh]--,siz[f[v]]++;
        }
    }
    
    inline void newnote(long long u,long long v){to[++cnt]=v,nxt[cnt]=fir[u],fir[u]=cnt;}
    
    inline void init()
    {
        ksm1[1]=ksm2[1]=1;
        for(long long i=2;i<=maxn;i++)
        {
            ksm1[i]=(ksm1[i-1]*(maxn+1)%mod1);
            ksm2[i]=(ksm2[i-1]*(maxn+1)%mod2);
        }
    }
    
    int main()
    {
        init();
        long long i,j;
        n=getint(),m=getint();
        for(i=1;i<=n;i++)sum[i]=(rd[i]=getint())+sum[i-1];
        for(i=1;i<=n;i++)
            for(j=1;j<=rd[i];j++)
            {
                road[sum[i-1]+j].u=getint()+m*(i-1);
                road[sum[i-1]+j].v=getint()+m*(i-1);
                road[sum[i-1]+j].w=getint(),road[sum[i-1]+j].bl=i;
                newnote(road[sum[i-1]+j].u,road[sum[i-1]+j].v);
                newnote(road[sum[i-1]+j].v,road[sum[i-1]+j].u);
            }
        for(i=1;i<=n*m;i++)
        {
            f[i]=i,siz[i]=1;
            hash1[(i-1)%m+1]=(hash1[(i-1)%m+1]+(i*ksm1[(i-1)/m+1]%mod1))%mod1;
            hash2[(i-1)%m+1]=(hash2[(i-1)%m+1]+(i*ksm2[(i-1)/m+1]%mod2))%mod2;
        }
        sort(road+1,road+sum[n]+1,cmp);
        q=getint();
        for(i=1;i<=q;i++)
            dri[i].u=getint(),dri[i].v=getint(),dri[i].w=getint(),dri[i].bl=i;
        sort(dri+1,dri+q+1,cmp);
        long long tmp=1;
        for(i=1;i<=sum[n];i++)
        {
            while(road[i].w<dri[tmp].w&&tmp<=q)
            {
                if(hash1[dri[tmp].u]==hash1[dri[tmp].v]&&hash2[dri[tmp].u]==hash2[dri[tmp].v])
                    ans[dri[tmp].bl]=1;
                tmp++;
            }
            if(f[road[i].u]!=f[road[i].v])work(i);
        }
        while(tmp<=q)
        {
            if(hash1[dri[tmp].u]==hash1[dri[tmp].v]&&hash2[dri[tmp].u]==hash2[dri[tmp].v])
                ans[dri[tmp].bl]=1;
            tmp++;
        }
        for(i=1;i<=q;i++)
            if(ans[i])printf("yes
    ");
            else printf("no
    ");
    }
  • 相关阅读:
    strtok() and strtod()
    quernation,euler,rotationmatrix之间的相互转换
    Ubuntu16.04+Ros+Usb_Cam ORB SLAM2
    windows10下VS2013搭建opencv2.4.9吐血之作
    深度学习之numpy.poly1d()函数
    matplotlib动态图subplots()和subplot()不同及参数
    python学习之matplotlib绘制动图(FuncAnimation()参数)
    javascipt——jQuery
    Javascript——(2)DOM
    linux nc 命令详解
  • 原文地址:https://www.cnblogs.com/Darknesses/p/12002542.html
Copyright © 2020-2023  润新知