首页 > 其他分享 >G - AtCoder Office

G - AtCoder Office

时间:2024-08-10 17:50:39浏览次数:17  
标签:AtCoder 20 Office office int leq time 区间

G - AtCoder Office

Problem Statement

$N$ people work at the AtCoder office.

The office keeps records of entries and exits, and there have been $M$ entries and exits since the records began.

The $i$-th $(1\leq i\leq M)$ record is represented by a pair of integers $(T_i, P_i)$, indicating that at time $T_i$, the $P_i$-th person either entered the office if they were outside, or exited the office if they were inside.

It is known that all people were outside the office at the beginning of the records, and they are outside now.

Answer $Q$ queries in the following format.

For the $i$-th $(1\leq i\leq Q)$ query, you are given a pair of integers $(A_i, B_i)$. Find the total length of the periods during which both the $A_i$-th and $B_i$-th persons were inside the office since the records began.

Constraints

  • $2\leq N\leq2\times10^5$
  • $2\leq M\leq2\times10^5$
  • $1\leq T_1\lt T_2\lt\dotsb\lt T_M\leq10^9$
  • $1\leq P_i\leq N\ (1\leq i\leq M)$
  • For every $1\leq p\leq N$, the number of indices $i$ such that $P_i=p$ is even.
  • $1\leq Q\leq2\times10^5$
  • $1\leq A_i\lt B_i\leq N\ (1\leq i\leq Q)$
  • All inputs are integers.

Input

The input is given from Standard Input in the following format:

$N$ $M$
$T_1$ $P_1$
$T_2$ $P_2$
$\vdots$
$T_M$ $P_M$
$Q$
$A_1$ $B_1$
$A_2$ $B_2$
$\vdots$
$A_Q$ $B_Q$

Output

Print $Q$ lines. The $i$-th line $(1\leq i\leq Q)$ should contain the answer to the $i$-th query.


Sample Input 1

3 8
10 1
20 2
30 1
40 3
60 3
70 1
80 2
90 1
3
1 2
1 3
2 3

Sample Output 1

20
0
20

The following diagram shows the time each of the three people spent inside the office.

The answers to each query are as follows:

  • The 1st and 2nd persons were both inside the office from time $20$ to time $30$ and from time $70$ to time $80$. The lengths of these two periods are both $10$, so print the total, which is $20$.
  • The 1st and 3rd persons were never inside the office at the same time, so print $0$.
  • The 2nd and 3rd persons were both inside the office from time $40$ to time $60$. The length of this period is $20$, so print $20$.

Sample Input 2

10 20
10257 9
10490 4
19335 1
25893 5
32538 9
33433 3
38522 9
40629 9
42896 5
52106 1
53024 3
55610 5
56721 9
58286 9
63128 3
70513 3
70977 4
74936 5
79883 9
95116 9
7
1 3
3 9
1 9
4 9
1 5
5 9
3 5

Sample Output 2

18673
2107
15310
25720
17003
10317
16848

 

解题思路

  题意大概是每个人有若干个互不相交的区间,每次询问两人交集的长度是多少。看到时限 $5$ 秒一般时间复杂度都是带根号的,因此容易想到分块或根号分治的做法。

  由于所有人的区间总数是恒定的,因此可以考虑根据每个人的区间数量进行分类。设阈值 $M = O(\sqrt{m})$,那么区间数量超过 $M$ 的人数大概就是 $O(\frac{m}{M}) = O(\sqrt{m})$ 级别。对于每个区间数量超过 $M$ 的人,我们可以通过遍历 $m$ 条记录预处理出该人与其他人的交集长度,时间复杂度为 $O((n+m) \sqrt{m})$。因此在询问时,如果两人的区间数量都不超过 $M$,直接暴力枚举区间求交集即可,时间复杂度为 $O(\sqrt{m})$,否则直接查表。

  思想比较简单,但实现就相对困难。下面先给出如何通过 $O(m)$ 的方法求出第 $i$ 个人与其他人的交集。由于 $m$ 条记录对应的时间没用重复且依次递增,这相当于进行了离散化。定义 $\mathrm{last}_j$ 表示第 $j$ 个人上一条记录的编号,如果上条记录对应区间右端点则设为 $0$。定义前缀和 $s_j$ 表示第 $i$ 个人的前 $j$ 条记录中区间的总长度,转移方程为 $\displaylines{\begin{cases} s_j = s_{j-1} + t_j - t_{j-1}, &\mathrm{last}_i \ne 0 \\ s_j = s_{j-1}, &\mathrm{last}_i = 0 \end{cases}}$。因此当遍历到第 $j$ 条记录时,如果对应的是第 $p_j$ 个人的右端点,那么第 $i$ 个人与第 $p_j$ 个的人的交集长度就是 $s_{j} - s_{\mathrm{last}_{p_j}}$,将该结果累加到两人的总交集长度中。

  剩下的就是如何求出两个区间数量不超过 $M$ 的人的交集长度。每个人的区间按左端点排序,并分别维护一个指针,假设一个人当前的区间是 $[l_i, r_i]$,另外一个人是 $[l_j, r_j]$,那么这两个区间的交集为 $\max\{0, \, \min\{ r_i, r_j \} - \max\{ l_i, l_j \} \}$。然后如果 $r_i < r_j$,则让 $i$ 加 $1$ 移到下个区间,否则让 $j$ 加 $1$。

  AC 代码如下,时间复杂度为 $O((n+m+q) \sqrt{m})$:

#include <bits/stdc++.h>
using namespace std;

typedef long long LL;

const int N = 2e5 + 5, M = 1000;

array<int, 2> a[N];
vector<int> g[N];
int s[N], c[N], last[N];
map<array<int, 2>, int> mp;

int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    int n, m, k;
    cin >> n >> m;
    for (int i = 1; i <= m; i++) {
        cin >> a[i][0] >> a[i][1];
        g[a[i][1]].push_back(a[i][0]);
    }
    for (int i = 1; i <= n; i++) {
        if (g[i].size() < M) continue;
        memset(c, 0, n + 1 << 2);
        for (int j = 1; j <= m; j++) {
            s[j] = s[j - 1] + (a[j][0] - a[j - 1][0]) * !!last[i];
            if (a[j][1] != i && last[a[j][1]]) c[a[j][1]] += s[j] - s[last[a[j][1]]];
            last[a[j][1]] = last[a[j][1]] ? 0 : j;
        }
        for (int j = 1; j <= n; j++) {
            if (j < i) mp[{j, i}] = c[j];
            else if (j > i) mp[{i, j}] = c[j];
        }
    }
    cin >> k;
    while (k--) {
        int x, y;
        cin >> x >> y;
        if (g[x].size() < M && g[y].size() < M) {
            int ret = 0;
            for (int i = 0, j = 0; i < g[x].size() && j < g[y].size(); ) {
                ret += max(0, min(g[x][i + 1], g[y][j + 1]) - max(g[x][i], g[y][j]));
                if (g[x][i + 1] < g[y][j + 1]) i += 2;
                else j += 2;
            }
            cout << ret << '\n';
        }
        else {
            cout << mp[{x, y}] << '\n';
        }
    }
    
    return 0;
}

 

参考资料

  Editorial - Toyota Programming Contest 2024#8(AtCoder Beginner Contest 365):https://atcoder.jp/contests/abc365/editorial/10610

标签:AtCoder,20,Office,office,int,leq,time,区间
From: https://www.cnblogs.com/onlyblues/p/18352572

相关文章

  • AtCoder Regular Contest 100 F Colorful Sequences
    洛谷传送门AtCoder传送门比较有趣的一个题。考虑一个弱化版,算colorful序列个数。有一个\(O(nK)\)的dp,大概就是设\(f_{i,j}\)为考虑到第\(i\)个数,当前最长互不相同后缀长度为\(j\)。转移考虑若往后面填一个在这\(j\)个数以外的数就能使\(j\getsj+1\),因此\(......
  • 万户OA ezOFFICE graph_include.jsp接口SQL注入漏洞复现 [附POC]
    文章目录万户OAezOFFICEgraph_include.jsp接口SQL注入漏洞复现[附POC]0x01前言0x02漏洞描述0x03影响版本0x04漏洞环境0x05漏洞复现1.访问漏洞环境2.构造POC3.复现0x06修复建议万户OAezOFFICEgraph_include.jsp接口SQL注入漏洞复现[附P......
  • 泛微E-office 10 schema_mysql接口敏感信息泄露漏洞复现 [附POC]
    文章目录泛微E-office10schema_mysql接口敏感信息泄露漏洞复现[附POC]0x01前言0x02漏洞描述0x03影响版本0x04漏洞环境0x05漏洞复现1.访问漏洞环境2.构造POC3.复现泛微E-office10schema_mysql接口敏感信息泄露漏洞复现[附POC]0x01前言......
  • php 使用phpoffice/phpword导出word
    安装指令composerrequirephpoffice/phpword 基本设置/***//设置常用文本样式*'size'=>12,//文字大小*'name'=>'宋体',//字体名称*'bold'=>true,//加粗*'italic'......
  • 文档控件DevExpress Office File API v24.1 - 支持基于Unix系统的打印
    DevExpressOfficeFileAPI是一个专为C#,VB.NET和ASP.NET等开发人员提供的非可视化.NET库。有了这个库,不用安装MicrosoftOffice,就可以完全自动处理Excel、Word等文档。开发人员使用一个非常易于操作的API就可以生成XLS,XLSx,DOC,DOCx,RTF,CSV和SnapReport等企业级文......
  • DzzOffice 网盘插件的文件属性中显示文件位置、直链地址
    文件:dzz\explorer\template\ajax.htm在代码<!--{if$propertys[fdateline]}--><divclass="file-natureclearfix"><labelclass="col-md-4col-sm-4col-xs-4">{langcreate_time}</label><divclass=&......
  • DzzOffice系统与插件更新日志
    2024/07/23PDFTron1.支持将编辑后的PDF文件保存到Dzz中:实现了编辑与存储的无缝对接,简化了文件处理流程,减少了用户的操作步骤,提高了工作效率。2.对接Dzz的文件权限管理:用户在保存PDF文件时,可以自动应用DzzOffice中设置的文件权限规则。这意味着文件的查看、编辑、下载等权......
  • DzzOffice 新闻插件查看页面添加水印
    文件:\dzz\news\template\news_view.htm这里以显示用户名水印为示例<scripttype="text/javascript">//需要用到的地方调用就好watermark({watermark_txt:'$_G[username]'})functionwatermark(settings){//默认设置vardefaultSettings={......
  • PageOffice6国产Linux系统最简集成代码(.NetCore)
    本文描述了PageOffice产品在.NetCore项目中如何集成调用。PageOffice国产版:支持信创系统,支持银河麒麟V10和统信UOS,支持X86(intel、兆芯、海光等)、ARM(飞腾、鲲鹏、麒麟等)、longarch芯片架构。新建.NetCore项目:PageOffice6-Net-Core-Simple在此项目的“依赖项-包-管理NuGet程序......
  • vue 项目使用@vue-office/docx word 纯前端v 也支持后端接口方式
    只是做个记录,防止忘记。安装依赖 @vue-office/docxvue2的写法vue3同理自己改造。记得一定放在public文件夹下 下面代码<template> <divstyle="height:100%">  <el-buttontype="primary"@click="downWord">下载文档</el-button>  <vue......