首页 > 编程语言 >【尺取法】【二分】河南省第十三届ICPC大学生程序设计竞赛 C题

【尺取法】【二分】河南省第十三届ICPC大学生程序设计竞赛 C题

时间:2023-05-16 21:03:17浏览次数:63  
标签:cnt int ICPC 取法 ans 区间 第十三届 mp

题目链接:https://ac.nowcoder.com/acm/contest/57784/C
来源:牛客网

题目描述

有一个长度为 \(n\) 的序列 \(a_i\) 和常数 \(K\)。

总共选 \(m\) 次,每次选一个连续区间 \([L_i,R_i]\) ,问这个区间中存在多少个连续子区间满足,区间中不同的数的个数不小于 \(K\)。

首先用尺取法统计区间数字出现的次数,这是一种简单易行的暴力法。

定义 mp[x] 表示数字 \(x\) 出现的次数;定义 cnt 表示区间内不同数的个数;定义 f[i] 表示区间 \([i, f_i]\) 中有 \(k\) 个不同的数。

用指针 \(l, r\) 单向扫描,从数列头扫到尾,\(l, r\) 最终落在区间最右边。

\(r\) 每向右扫描一个数字,它出现的次数加1;\(l\) 每向右扫描一个数字,它出现的次数减1。

cnt 的值等于 \(K\) 时,记录此时的右指针 \(f[l]\gets r\)。

for (int l = 1, r = 1; l <= n; l++) {
    while (cnt < k && r <= n)
        if (++mp[a[r++]] == 1)
            cnt++;
    if (cnt == k)
        f[l] = r - 1;
    else
        f[l] = n + 1;
    if (--mp[a[l]] == 0)
        cnt--;
}

我们考虑如何计算子区间个数。

for (int i = l; i <= r; i++)
	if (f[i] <= r)
		cnt += r - f[i] + 1;

考虑到 \(f[i]\) 是单调递增的,那么可以二分查找 p = upper_bound(r) - 1

答案为 \((r+1)(p-l+1)-\sum\limits_{i=l}^{i\le p} f[i]=(r+1)(p-l+1)-(s[p]-s[l-1])\)。\(s[i]\) 为 \(f[i]\) 的前缀和。

参考代码

#include <bits/stdc++.h>
using namespace std;
using ll = long long;
const int N = 1e5 + 5;

int a[N], f[N];
ll s[N];
int n, m, k, cnt;
map<int, int> mp;

void add(int x) {
    if (++mp[a[x]] == 1)
        cnt++;
}
void del(int x) {
    if (--mp[a[x]] == 0)
        cnt--;
}

int main() {
    cin >> n >> m >> k;
    for (int i = 1; i <= n; i++)
        cin >> a[i];
    // 尺取法,f[i] 表示区间 [i, f[i]] 中有k个不同的数
    for (int l = 1, r = 1; l <= n; l++) {
        while (cnt < k && r <= n)
            add(r++);
        if (cnt == k)
            f[l] = r - 1;
        else
            f[l] = n + 1;
        del(l);
    }
    // 计算f的前缀和
    for (int i = 1; i <= n; i++)
        s[i] = s[i - 1] + f[i];

    ll ans = 0;
    while (m--) {
        ll l1, r1;
        cin >> l1 >> r1;
        int l = min(l1 ^ ans, r1 ^ ans) + 1;
        int r = max(l1 ^ ans, r1 ^ ans) + 1;
        // 二分
        ll p = upper_bound(f + 1, f + 1 + n, r) - f - 1;

        ans = 0;
        if (p >= l)
            ans = (r + 1) * (p - l + 1) - (s[p] - s[l - 1]);
        cout << ans << endl;
    }
}

标签:cnt,int,ICPC,取法,ans,区间,第十三届,mp
From: https://www.cnblogs.com/xtf0214/p/ICPC_HN2021_C.html

相关文章

  • 2023年电子科技大学ACM-ICPC暑假前集训-第一次队内赛
    Preface队内赛被吊打了呜呜呜,F死命贪心贪到天昏地暗,直接后面两题一眼没看其实后面对拍大概知道贪心是有问题的了,但以为可以用分类讨论来避免掉所以没去写DP(他其实什么都知道,只是不想面对罢了)感觉DP还是一如既往地是我的弱项的说,还得好好练习的说G和H其实比较常规,补题的时候一......
  • 2020ICPC南京J
    以前没写过势能线段树,然后错了114514个地方,我有罪。#include<bits/stdc++.h>usingnamespacestd;constintN=200013;inta[N];structsegtree{#definemid((l+r)>>1)#definelsx<<1,l,mid#definersx<<1|1,mid+1,r#definelctr[x<<1]#definerct......
  • The 2022 ICPC Asia Hangzhou Regional Programming Contest--M题 (字典树)
    https://codeforces.com/gym/104090/problem/K题意:给你n个字符串,在给你m个字符大小顺序规则。求逆序对数量。1.常规求这n个字符串的逆序对数量O(n^2)的时间复杂度,必爆,肯定要想办法优化,就往预处理上想。2.在不同规则下,比较这n个字符串谁大,两个字符串比较谁大,无论什么字符串大,......
  • 洛谷 P6938 - [ICPC2017 WF]Son of Pipe Stream(网络流)
    见过的最怪的网络流题,没有之一。首先新建超级源点,向\(1,2\)各连\(\infty\)的边。设最大流为\(A\),那么显然最优方案中flutter和water流量之和为\(A\)。先分析一波答案函数。显然,最终答案关于flutter的流量\(x\)的函数\(f(x)=x^a(A-x)^{1-a}\)。求导得\(f'(x)=ax^......
  • 尺取法
    尺取法又叫双指针(twopointers)是竞赛中常用的优化基技巧,用来解决区间问题,操作简单。如果是单调区间也常用二分法需要操作两个变量,可以用两个下标(指针)i,j扫描区间。有二重循环,复杂度为O(n2)for(inti=0;i<n;i++)for(intj=n-1;j>=0;j--){}实际上尺......
  • 2023年电子科技大学ACM-ICPC暑假前集训-数据结构
    Preface学校针对大一新生的暑假前集训的第一个专题DS,由于要求集体写题解就顺便把写好的发上来了由于下面都写了题意所以直接看也能有很多收获,当然非电专的学生的话就没法交题了代码的话由于专题还没结束怕放上来然后被CV导致被爆破,所以应该在这周六专题结束后会放上来下面都是......
  • 2016 ACM/ICPC Asia Regional Qingdao Online E
    Rock-paper-scissorsisazero-sumhandgameusuallyplayedbetweentwopeople,inwhicheachplayersimultaneouslyformsoneofthreeshapeswithanoutstretchedhand.Theseshapesare“rock”,“paper”,and“scissors”.Thegamehasonlythreepossible......
  • 2017 ACM-ICPC, Universidad Nacional de Colombia Programming Contest D
    AlexhastwomagicmachinesAandB.MachineAwillgiveyou2x + 1coinsifyouinsertxcoinsinit,machineBwillgiveyou2x + 2.Alexhasnocoinsandwantstogetexactlyncoinsinordertobuyanewunicorn,buthecan’tfigureouthowtodoi......
  • 2016 ACM/ICPC Asia Regional Qingdao Online B
    Givenanintegern,weonlywanttoknowthesumof1/k2wherekfrom1ton.InputTherearemultiplecases.Foreachtestcase,thereisasingleline,containingasinglepositiveintegern.Theinputfileisatmost1M.OutputTherequiredsum,......
  • 2017ACM/ICPC广西邀请赛-重现赛(感谢广西大学)C - Counting Stars 暴力三元环
    LittleAisanastronomylover,andhehasfoundthattheskywassobeautiful!Soheiscountingstarsnow!Therearenstarsinthesky,andlittleAhasconnectedthembymnon-directionaledges.Itisguranteedthatnoedgesconnectonestarwithi......