首页 > 其他分享 >「解题报告」UOJ605 [UER #9] 知识网络

「解题报告」UOJ605 [UER #9] 知识网络

时间:2023-04-12 16:24:09浏览次数:39  
标签:UER int 标签 短路 解题 MAXN bitset UOJ605 dis

好像并不是很难的题?虽然从上午想到现在才开始写,还因为不知道 __builtin_popcount(x) 传入的是 int 调了一个多小时

题目就是要求一个全源最短路。直接求显然不太现实,考虑分析标签的性质。发现,同一标签内的所有点到某个点 \(u\) 的最短路的差值一定不超过 \(1\),因为同一标签下的点可以互相到达。那么,如果我们可以求出同一标签下的所有点到每个点的最短路,并且求出有多少点到这个点是最短路即可。

前者是好处理的,直接跑最短路就可以做到 \(O(km \log m)\)。由于是 01 最短路,跑 BFS 即可做到 \(O(km)\),Dijkstra 也能过。

后者我们可以建出最短路 DAG,那么我们就是要统计有多少个点能够在 DAG 上到达每个点。这东西看起来就不像是什么正经算法能做的东西,所以我们直接考虑 bitset。我们只需要建出 DAG,然后拓扑排序并且跑 bitset 即可。但是这样复杂度就是 \(O(\frac{kn^2}{\omega})\) 了..吗?

实际上,每次的 bitset 大小只需要开标签的个数即可,而每个标签的数量总和显然是 \(O(n)\),那么我们可以手动实现一个不定长 bitset,然后再跑,复杂度就是 \(O(\frac{n^2}{\omega})\) 了,可以通过。

然后你就被 Extra Test 创飞了。

发现空间限制 256MB,空间复杂度 \(O(\frac{n^2}{\omega})\) 是无法接受的。这时候,我们可以应用 毒瘤 lxl 在毒瘤分块题中卡空间的常见做法 来解决,即每 \(\omega\) 个数分一块,然后每次只计算每一块的答案,最后加起来即可。空间复杂度降至 \(O(n)\)。

然后记得使用 __builtin_popcountll

#include <bits/stdc++.h>
using namespace std;
const int MAXN = 510005;
int n, m, k;
int p[MAXN];
vector<pair<int, int>> e[MAXN];
const int B = 6, MASK = (1 << B) - 1;
vector<int> pt[MAXN];
long long ans[MAXN];
unsigned long long f[MAXN];
int dis[MAXN];
bool vis[MAXN];
struct DAG {
    vector<int> e[MAXN];
    int deg[MAXN], de[MAXN];
    void add(int u, int v) {
        e[u].push_back(v);
        de[v]++;
    }
    void clear() {
        for (int i = 1; i <= n + k; i++) {
            e[i].clear();
            de[i] = 0;
        }
    }
    void topo() {
        for (int i = 1; i <= n + k; i++) deg[i] = de[i];
        queue<int> q;
        for (int i = 1; i <= n + k; i++) if (!deg[i]) q.push(i);
        while (!q.empty()) {
            int u = q.front(); q.pop();
            for (int v : e[u]) {
                f[v] |= f[u];
                deg[v]--;
                if (!deg[v]) q.push(v);
            }
        }
    }
} g;
int main() {
    scanf("%d%d%d", &n, &m, &k);
    for (int i = 1; i <= n; i++) {
        scanf("%d", &p[i]);
        pt[p[i]].push_back(i);
        e[n + p[i]].push_back({i, 1});
        e[i].push_back({n + p[i], 0});
    }
    for (int i = 1; i <= m; i++) {
        int u, v; scanf("%d%d", &u, &v);
        e[u].push_back({v, 1});
        e[v].push_back({u, 1});
    }
    for (int i = 1; i <= k; i++) {
        int m = pt[i].size();
        for (int j = 1; j <= n + k; j++) vis[j] = 0, dis[j] = INT_MAX / 2;
        priority_queue<pair<int, int>, vector<pair<int, int>>, greater<pair<int, int>>> q;
        for (int j : pt[i]) q.push({0, j}), dis[j] = 0;
        while (!q.empty()) {
            int u = q.top().second; q.pop();
            if (vis[u]) continue;
            vis[u] = 1;
            for (auto p : e[u]) {
                int v = p.first, w = p.second;
                if (vis[v]) continue;
                if (dis[v] > dis[u] + w) {
                    dis[v] = dis[u] + w;
                    q.push({dis[v], v});
                }
            }
        }
        g.clear();
        for (int u = 1; u <= n + k; u++) {
            for (auto p : e[u]) {
                int v = p.first, w = p.second;
                if (dis[v] == dis[u] + w) {
                    g.add(u, v);
                }
            }
        }
        for (int l = 0, r; l < m; l = r + 1) {
            r = min(l + 63, m - 1);
            for (int j = 1; j <= n + k; j++) f[j] = 0;
            for (int j = l; j <= r; j++) f[pt[i][j]] |= 1ull << (j - l);
            g.topo();
            for (int j = 1; j <= n; j++) {
                if (dis[j] < INT_MAX / 2) {
                    ans[dis[j]] += __builtin_popcountll(f[j]);
                    ans[dis[j] + 1] += (r - l + 1) - __builtin_popcountll(f[j]);
                } else {
                    ans[2 * k] += (r - l + 1);
                }
            }
        }
    }
    printf("0 ");
    for (int i = 1; i <= 2 * k; i++) printf("%lld ", ans[i] / 2);
    return 0;
}

标签:UER,int,标签,短路,解题,MAXN,bitset,UOJ605,dis
From: https://www.cnblogs.com/apjifengc/p/17310186.html

相关文章

  • Java:使用hutool工具类UrlBuilder、urlQuery构建url查询参数
    依赖<dependency><groupId>cn.hutool</groupId><artifactId>hutool-all</artifactId><version>5.4.6</version></dependency>url查询参数构建packagecom.example;importcn.hutool.core.net.url.UrlQuery;im......
  • jQueryUI教程_编程入门自学教程_菜鸟教程-免费教程分享
    教程简介JqueryUI入门教程-从基本到高级概念的简单简单步骤了解JqueryUI,其中包括概述,环境设置,交互,可拖动,可放置,可调整大小,可选,可排序,小部件,手风琴,自动完成,按钮,Datepicker,对话框,菜单,Progressbar,Slider,Spinner,Tabs,Tooltip,Effects,AddClass,ColorAnimation,Effect,Hide,RemoveClass......
  • 约瑟夫环问题---&解题方法 静态单链表&一维数组
      importjava.util.Scanner;publicclassMain{publicstaticvoidmain(String[]args){Scannerinput=newScanner(System.in);intn=input.nextInt();intm=input.nextInt();int[]ant=newint[150];for(int......
  • Pandas Query 方法深度总结,你学会了吗?
    [PandasQuery方法深度总结,你学会了吗?-51CTO.COM](https://www.51cto.com/article/714736.html) 数据库其他数据库事实证明实际上可以使用query()​方法做到这一点。因此,在今天的文章中,我们将展示如何使用query()方法对数据框执行查询。大多数Pandas用户都熟悉 ilo......
  • mouted阶段无法通过querySelectAll获取dom元素
    要获取的元素是通过v-for渲染出来的时候,dom元素依赖的数据是通过异步请求获取的,mouted时v-for的数据还没有获取到,故没有元素产生,mouted无法获取元素,可以使用nexttick和watch结合来用,监听dom元素依赖的数据变化,用nextTick来管理数据,在数据获取之后再获取dom元素......
  • postgresSQL Extended Query执行过程和sharding-proxy的处理
    pgExtendedQueryPostgreSQL:Documentation:15:55.2. MessageFlow多个阶段,可复用Parse→DESCRIBEstatement→SYNCParse解析,将sql文本字符串,解析成namedpreparedStatement语句(生命周期随session)占位符和参数类型Describe获取元数据,返回pst参数描述......
  • 「解题报告」P9169 [省选联考 2023] 过河卒
    挺套路的博弈论,实际上就是GameonGraph与GameonGraph,但是考场上多测没清空挂了。寄。并且不过ABC那个官方题解好像给的是\(O(m\logn)\)的做法,放这题是过不去的啦x首先显然三个棋子压状态大概是\(10^6\)级别的,多测\(T=10\),那么猜测是一个\(O(Tn^6)\)的做法。......
  • SpringMVC中使用引入jquery不能加载页面
    今天在学习springMVC的json数据绑定时,需要使用到jquery发送ajax请求。但是当我通过是<script>标签引入了jquery.js。但是当我访问该jsp的时候就是不显示页面的内容我一直以为时SpringMVC的servelt拦截器拦截了静态资源,但是我过滤了静态资源还是不显示。后来才发现,我把<script......
  • 整理房号(Power Query)
    问题:let源=Excel.CurrentWorkbook(){[Name="表1"]}[Content],替换租户=Table.ReplaceValue(源,"租户","",Replacer.ReplaceText,{"房号"}),替换二次装修=Table.ReplaceValue(替换租户,"(二次装修)","",Replacer.Rep......
  • 不需要第一行的多表合并(Power Query)
    问题:多工作表合并,但第一行不需要,标题行从第二行起。let源=Excel.Workbook(File.Contents("路径\文件名.xlsx")),规范表=Table.TransformColumns(源,{"Data",eachTable.PromoteHeaders(Table.Skip(_,1))}),删除列=Table.SelectColumns(规范表,{"Data"}),......