首页 > 其他分享 >20231126模拟赛

20231126模拟赛

时间:2023-11-28 19:33:08浏览次数:29  
标签:lf dn le 20231126 limits int max 模拟

2023.11.26 模拟赛

T1

给定数列 \(a_{1, \cdots, n}, b_{1, \cdots, m}\),一个 \(n \times m\) 的矩阵 \(W\) 满足 \(W_{i, j} = a_i + b_j\)。

给定常数 \(x\),问满足 \(W_{i, j} \le x\) 的所有格子 \((i, j)\) 形成的四连通块数量。

\(1 \le n, m, x, a_i, b_j \le 2 \times 10 ^ 5\)。

对于每一个连通块,必然有至少一行、至少一列贯穿了整个块,因为行与行、列与列之间 \(W_{i, j} \le x\) 的格子呈包含关系。

用一个连通块中数字最小的格子代表这个连通块。如果有多个选择最左边那个,仍有多个选择最上面那个。反证法容易证明先向上找再向左找会到达同一个格子。

考虑预处理出如下信息:

  • \(up_i\) 为最大的 \(1 \le i' < i\),使 \(W_{i', j} \le W_{i, j}\),若不存在则 \(up_i = i\)。

  • \(lf_j\) 为最大的 \(1 \le j' < j\),使 \(W_{i, j'} \le W_{i, j}\),若不存在则 \(lf_j = j\)。

  • \(dn_i\) 为最小的 \(i < i' \le n\),使 \(W_{i', j} < W_{i, j}\),若不存在则 \(dn_i = i\)。

  • \(rg_j\) 为最小的 \(j < j' \le m\),使 \(W_{i, j'} < W_{i, j}\),若不存在则 \(rg_j = j\)。

容易发现如果一个格子 \((i, j)\) 能够代表一个连通块,仅当 \(up_i, dn_i\) 要么等于 \(i\),要么和 \((i, j)\) 不在同一个连通块,\(lf_j, rg_j\) 同理。

定义 \(l > r\) 时 \(\max\limits_{l \le p \le r} a_p = +\infty\)。那么 \((i, j)\) 能代表连通块时:

\[\begin{cases} a_i + b_j \le x \\ a_i + \max\limits_{lf_j < p \le j} b_p > x \\ a_i + \max\limits_{j \le p \le rg_j} b_p > x \\ \max\limits_{up_i < p \le i} a_p + b_j > x \\ \max\limits_{i \le p < dn_i} a_p + b_j > x \end{cases} \]

记 \(f_i = \min (\max\limits_{up_i < p \le i} a_p, \max\limits_{i \le p < dn_i} a_p), g_j = \min (\max\limits_{lf_j < p \le j} b_p, \max\limits_{j \le p \le rg_j} b_p)\)。条件简化为:

\[\begin{cases} x - f_i < b_j \le x - a_i \\ g_j > x - a_i \end{cases} \]

将 \((b_j, g_j)\) 看作平面上的点,于是就是经典的二维数点问题,离线树状数组即可。

Code of T1
#include <bits/stdc++.h>
const int M = 2e5 + 10;
const int LIM = 200001;

int n, m, x, a[M], b[M], f[M], g[M];
int lf[M], rg[M], up[M], dn[M], stk[M], top;

void getdirqwq() {
    stk[top = 0] = 0;
    for (int i = 1; i <= n; i++) {
        while (top && a[i] < a[stk[top]]) top--;
        up[i] = top ? stk[top] : i, stk[++top] = i;
    }
    stk[top = 0] = 0;
    for (int i = 1; i <= m; i++) {
        while (top && b[i] < b[stk[top]]) top--;
        lf[i] = top ? stk[top] : i, stk[++top] = i;
    }
    stk[top = 0] = n + 1;
    for (int i = n; i >= 1; i--) {
        while (top && a[i] <= a[stk[top]]) top--;
        dn[i] = top ? stk[top] : i, stk[++top] = i;
    }
    stk[top = 0] = m + 1;
    for (int i = m; i >= 1; i--) {
        while (top && b[i] <= b[stk[top]]) top--;
        rg[i] = top ? stk[top] : i, stk[++top] = i;
    }
}

int _lg2[M];
struct STalbe {
    int st[20][M];
    void Build(int* a, int n) {
        for (int i = 1; i <= n; i++) st[0][i] = a[i];
        for (int j = 1; (1 << j) <= n; j++)
            for (int i = 1; i + (1 << j) - 1 <= n; i++)
                st[j][i] = std::max(st[j - 1][i], st[j - 1][i + (1 << (j - 1))]);
    }
    int Qmax(int l, int r) {
        if (l > r) return LIM;
        int k = _lg2[r - l + 1];
        return std::max(st[k][l], st[k][r - (1 << k) + 1]);
    }
} sA, sB;

struct BIT {
    int c[M];
    void Add(int x, int v) {
        for (; x <= LIM; x += (x & -x)) c[x] += v;
    }
    int Ask(int p) {
        int ans = 0;
        for (; p; p -= (p & -p)) ans += c[p];
        return ans;
    }
} T;

long long ans;
struct Query {
    int pos, bot, v;
    bool operator < (const Query& o) const {
        return pos < o.pos;
    }
} q[M << 1];
std::vector<int> pt[M];
int cntq;

int main() {
    freopen("cloud.in", "r", stdin);
    freopen("cloud.out", "w", stdout);
    _lg2[0] = -1;
    for (int i = 1; i < M; i++) _lg2[i] = _lg2[i >> 1] + 1;

    scanf("%d%d%d", &n, &m, &x);
    for (int i = 1; i <= n; i++) scanf("%d", &a[i]);
    for (int i = 1; i <= m; i++) scanf("%d", &b[i]);
    getdirqwq();
    
    sA.Build(a, n), sB.Build(b, m);
    for (int i = 1; i <= n; i++)
        f[i] = std::min(sA.Qmax(up[i] + 1, i), sA.Qmax(i, dn[i] - 1));
    for (int j = 1; j <= m; j++)
        g[j] = std::min(sB.Qmax(lf[j] + 1, j), sB.Qmax(j, rg[j] - 1));
    for (int j = 1; j <= m; j++) pt[b[j]].push_back(g[j]);
    
    for (int i = 1; i <= n; i++) {
        if (x - a[i] < 1) continue;
        q[++cntq] = { x - a[i], x - a[i], 1 };
        if (x - f[i] >= 0) q[++cntq] = { x - f[i], x - a[i], -1 };
    }
    std::sort(q + 1, q + 1 + cntq);
    
    for (int i = 1; i <= cntq; i++) {
        for (int j = q[i - 1].pos + 1; j <= q[i].pos; j++)
            for (int x : pt[j]) T.Add(x, 1);
        ans += q[i].v * (T.Ask(LIM) - T.Ask(q[i].bot));
    }
    printf("%lld\n", ans);
    return 0;
}

标签:lf,dn,le,20231126,limits,int,max,模拟
From: https://www.cnblogs.com/zzxLLL/p/17862775.html

相关文章

  • 数字域dB到模拟域dBm的换算
    Vrms、Vpk、W、dBm、dBW、dBuV、dBm/HzdBm的定义在通信工程中,功率的大小通常用是用dBm值来表示的,是一个对数度量,被定义为相对于1mW参考功率电平的分贝,即dBm代表每毫瓦分贝。因此,它是一个无量纲单位,实际上指定了功率比而不是功率。它的计算公式如下:dBm=10*log(P/1mW)其中P......
  • 解决AndroidStudio 模拟器无网络连接
    解决AndroidStudio模拟器无网络连接主要原因是安卓模拟器的dns和电脑的dns不一致引起的,可以修改安卓模拟器的dns即可找到安卓模拟器的名字修改安卓模拟器dns命令 #Pixel7_API_30_fei这个是你自己模拟器的名字,也就是第一步中找的的模拟器名字./emulator-avdPixel......
  • 模拟退火
    引入模拟退火,一种由金属退火启发的随机化(玄学)算法,。当问题的方案数及其巨大甚至是无穷,而且不是一个线性或单峰函数时,模拟退火是一个较好的解决方案。解释先介绍一下它的前置算法——爬山算法。爬山算法爬山算法是一种局部择优的方法,采用启发式方法,是对深度优先搜索的一种改......
  • DG中模拟failover故障与恢复
      转自 路人甲Java http://www.360doc.com/myfiles.aspx?reg=1&app=1&type=3  问题描述:情形是当主库真正出现异常之后,才会执行的操作,那么我们执行过failover 之后,如何在重新构建DG,这里我们利用flashbackdatabase来重构。模拟前主库要开启闪回区,否则要重新搭......
  • Android 模拟器横向视图
    HowtochangeAndroidemulatortolandscapemode?ctrl + fn + F11 on Mac to change the landscape to portrait and vice versa.left-ctrl + F11 on Windows 7.ctrl + F11 on Linux.......
  • 多线程.模拟龟兔赛跑
    packageJavaSE.Thread.document01;/***模拟龟兔赛跑*/publicclassDemo05implementsRunnable{publicstaticStringwinner;//胜者@Overridepublicvoidrun(){for(inti=1;i<=100;i++){if(Thread.currentThread().getName()......
  • C语言模拟进程状态
    精选状态图如下给出C语言执行状态图根据状态图,给出C语言代码解释这段代码定义了一个枚举类型ProcessState,包含了5个枚举值:NEW、READY、RUNNING、BLOCKED和TERMINATED。然后定义了一个ProcessState类型的变量process,并将其初始化为NEW。接着通过printf语句输出当前进程状态......
  • C语言模拟进程状态
    首先定义进程状态的枚举类型为ProcessStatetypedefenum{NEW,READY,RUNNING,BLOCKED,TERMINATED}ProcessState;而后据图中进程运行代码intmain(){ProcessStateprocess=NEW;printf("Processcreated.State:NEW\n");process=REA......
  • 郑轻工 3097. 筛质数 + 二分 = 小模拟
    importjava.util.Arrays;importjava.util.Scanner;classMain{staticint[]pri=newint[100];staticintidx;publicstaticvoidmain(String[]args){Scannersc=newScanner(System.in);intx=sc.nextInt();init......
  • 20231126GESP三级笔记
    逛商场点击查看代码#include<bits/stdc++.h>usingnamespacestd;constintN=1e6+10;intn,a[N],x,ans=0;intmain(){cin>>n;for(inti=1;i<=n;i++)cin>>a[i];cin>>x;for(inti=1;i<=n;i++){if(a[i]<=......