首页 > 其他分享 >Make Rounddog Happy 启发式分治

Make Rounddog Happy 启发式分治

时间:2023-01-01 12:45:02浏览次数:38  
标签:int fcy Make pos Rounddog lR rL rep Happy

//题意:给定一个序列,询问他有多少个合法子序列
//      合法条件:在区间内不会出现相同的数,同时 区间最大值-(区间长度)<= 给定常数k
//思路:启发式分治,详情见博客
#include<bits/stdc++.h>
#define ll long long
#define rep(i,a,b) for(int i=a;i<=b;i++)
using namespace std;
const int maxn = 3e5 + 10;
int a[maxn], st[maxn][21], lg[maxn], K, N; 
ll ans;
int A[maxn], B[maxn], vis[maxn];
int get(int L, int R)
{
    int k = lg[R - L + 1];
    return a[st[L][k]] >= a[st[R - (1 << k) + 1][k]] ? st[L][k] : st[R - (1 << k) + 1][k];
}
void solve(int L, int R) {
    if (L > R) return;
    int pos = get(L, R);//返回区间最大值位置
    if (pos - L < R - pos) {
        rep(i, L, pos) {
            int t = a[pos] - K, lR = i + t - 1;
            int fcy = min(R, B[i]);
            lR = max(lR, pos);
            if (lR > fcy) continue;
            ans += fcy - lR + 1;
        }
    }
    else {
        rep(i, pos, R) {
            int t = a[pos] - K, rL = i - t + 1;
            int fcy = max(L, A[i]);
            rL = min(rL, pos);
            if (rL < fcy) continue;
            ans += rL - fcy + 1;
        }
    }
    solve(L, pos - 1); solve(pos + 1, R);
}
int main() {
    int T;
    lg[0] = -1; rep(i, 1, maxn - 1) lg[i] = lg[i >> 1] + 1;//提前维护出log2
    cin >> T;
    while (T--) {
        cin >> N >> K; ans = 0;
        rep(i, 1, N) cin >> a[i];
        rep(i, 1, N) st[i][0] = i;//区间长度为1当然是自己最大啦
    
    rep(i, 1, 20) {
        for (int j = 1; j + (1 << i) - 1 <= N; j++) {
            st[j][i] = a[st[j][i - 1]] >= a[st[j + (1 << (i - 1))][i - 1]] ? st[j][i - 1] : st[j + (1 << (i - 1))][i - 1];
        }
    }//ST表维护出最大值的位置 

    rep(i, 1, N) vis[i] = 0;
    A[1] = 1; vis[a[1]] = 1;

    rep(i, 2, N) {
        if (vis[a[i]]) A[i] = max(A[i - 1], vis[a[i]] + 1);
        else A[i] = A[i - 1];
        vis[a[i]] = i;
    }

    rep(i, 1, N) vis[i] = 0;
    B[N] = N; vis[a[N]] = N;
    for (int i = N - 1; i >= 1; i--) {
        if (vis[a[i]]) B[i] = min(B[i + 1], vis[a[i]] - 1);
        else B[i] = B[i + 1];
        vis[a[i]] = i;
    }
        solve(1, N);
        cout << ans << endl;
    }
    return 0;
}

 

 

 

 

 

标签:int,fcy,Make,pos,Rounddog,lR,rL,rep,Happy
From: https://www.cnblogs.com/Aacaod/p/17017953.html

相关文章

  • Linux下gcc命令运行c程序以及makefile文件
    GCC原名为GNUC语言编译器(GNUCCompiler),因为它原本只能处理C语言。GCC很快地扩展,变得可处理C++。后来又扩展为能够支持更多编程语言,如Fortran、Pascal、Objective-C......
  • 生成 makefile
     Makefile.am和makefile.in生成Makefilehttps://www.cnblogs.com/bigbear1385/p/6604765.htmlMakefile.am和makefile.in生成Makefile很多时候,我们在网上下载的linux开......
  • make: *** No rule to make target Stop.问题解决记录
    今天使用MounRiverStudio编写MCU程序时,遇到报错make:***Noruletomaketarget'D:/work_2022/13-617充电器/CH32V307EVT/EVT/EXAM/SRC/Peripheral/src/ch32v30x_adc.......
  • 使用CMake构建QCustomPlot
    因为原项目是使用CMake构建的,而且包含其他非标准库,同时并没有系统性学习CMake,还有Qt使用的QMake现在需要在原项目的基础上加上实时绘制曲线图,以方便查看数据和调试那么最......
  • make_pair 简单使用
    code:#include<iostream>usingnamespacestd;intmain(){autopair_1=make_pair(1,"2");cout<<pair_1.first<<endl;cout<<pair_1.second<<endl;autopa......
  • cmake基础
    其实就是翻译了一下cmake文档中的"cmake-language"cmake中的文件使用"cmake语言"来写一个项目中的cmake文件有如下几种形式当cmake处理一个项目时,起始点是项目根目......
  • linux Makefile 如何将生成的 .o 文件放到指定文件夹
    一、Makefile文件为了方便分析,直接上文件,Makefile文件中的内容如下所示:##Makefile#编译的.o文件和.c文件在同一路径下#$(info"start...")#可执行文件名PROJE......
  • 一文详解为什么需要用CMake来管理大型C++工程
    场景1:编译普通C++代码/*hello_world.cpp*/#include<iostream>usingnamespacestd;intmain(){cout<<"Hello,world!"<<endl;return0;}编译......
  • CMake梳理依赖关系
    梳理依赖关系的方法,通常是在cmake命令中追加参数graphviz,如cmake..--graphviz=../target_deps_graphviz,用来生成每个目标的依赖dot文件,再结合dot命令,如dot-Tpng-otar......
  • windows上clion+minGW+cmake配置G-Nut/Anubis
    注:这里只讲Anubis的配置,windows上clion、minGW和cmake的安装请参考别的博客! 源码下载地址:https://gnutsoftware.com/software/anubis下滑鼠标,找到下载区,点击”Getfree......