1006

巧了我就是萌 提交于 2019-11-30 19:33:01

A

打表+线性筛求质数的时候维护劳伦斯数+前缀和优化
原理同质数晒的原理:\(i \times prime[j]\)只会出现一次,保证了\(O(N)\)的复杂度
我又双叒叕没想到
黄学长的博客如下

for(int i=2;i<=1e7;i++)
    {
        if(!book[i]){prime[++cnt]=i;mark[i]=true;}
        for(int j=1;j<=cnt&&1ll*prime[j]*i<=1e7;j++)
        {
            book[i*prime[j]]=true;
            if(!book[i])mark[i*prime[j]]=true;
            if(i%prime[j]==0)break;
        }
    }
     for(int i=2;i<=1e7;i++)sum[i]=sum[i-1]+mark[i];

B

dijikstra+状压(K<=10)
设 dis[i][s] 表示到i号点时,手中的通行卡的集合为s的最短距离
讨论每个点的边时,需要if((need[i]&x.s)==need[i])判断这条边是否能通行,再讨论是否能更新这条边所连点的dis值

然而\(50%\)\(K=0\)的分我都没拿到,起因是

dijkstra

首先,dijikstra的重载运算符这样写

struct iakioi{
    int id;
    int dis;
    bool operator <(const iakioi &a)const{
        return a.dis>dis;
    }
}tmp;

看清楚了,重载都是>号不是<号,否则priority_queue将会从大到小排列

其次

while (!Q.empty()){
    int u = Q.top().Num;
    Q.pop();
    if (mark[u]) continue;
    mark[u] = true;
    for (int i=Last[u]; i!=0; i=Next[i]){
        int v = End[i];
        if (!mark[v] && dis[v] > dis[u] + Len[i]){
            dis[v] = dis[u] + Len[i];
            tmp.Num = v; tmp.dis = dis[v];
            Q.push(tmp);
        }
    }
}

这个写法是错误的
具体错误在这里

res(i,x){
    int v = End[i];
    //////////////////////////////////////////
    if (!mark[v] && dis[v] > dis[u] + Len[i]){
    //////////////////////////////////////////
        dis[v] = dis[u] + Len[i];
        tmp.Num = v; tmp.dis = dis[v];
        Q.push(tmp);
    }
}

其实这个v点有没有在堆里都是可以的QwQ(Mark[v]=1也没有关系)
也就是说这个写法应该是

res(i,x){
    int v = End[i];
    //////////////////////////////////////////
    if (dis[v] > dis[u] + Len[i]){
    //////////////////////////////////////////
        dis[v] = dis[u] + Len[i];
        tmp.Num = v; tmp.dis = dis[v];
        Q.push(tmp);
    }
}

C

把三个点两两求LCA ,取其中深度最大的LCA,答案就是dis(LCA,z)
好像是一个结论
未完待续...

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!