题意:对于1<=i<=n每次找到(pos[i]-k,pos[i]+k)内不大于i的最大那个数,ans[i]=ans[mx]+1,若ans[mx]未知则递归处理ans[mx]

PS:这个题比赛时写主席树k前驱没剪枝T了,然而实验室里的同学n^2过10w...自闭

主席树k前驱:在[l,r]范围内找到比k小的最大值,本质是带剪枝的主席树树上dfs

主要算法思想:当前区间[l,r]的sum(数字个数)为0则剪枝,l==r时,如果l<k说明l是k的前驱,否则说明不存在k的前驱,查找时,如果k<=m+1(m=(l+r)/2)或者右区间不存在数字(数字个数为0)时,返回递归求左区间的答案(注意为什么是m+1,因为当k<=m+1时,小于k的值必定只可能出现在左区间[l,m]中),否则查找右区间,当递归右区间有解,则必为最优解,直接返回这个解即可,当右区间无解,才继续递归左区间求解

这样一系列剪枝以后,这个算法就可以跑的很快了!

其实还有个想法就是二分第k大值去求,这个思路比较简单而且复杂度是O(nlogn^2),不知道会不会T,有时间了尝试补上

AC代码:

#include <bits/stdc++.h>
using namespace std;
const int N = 1e5+;
struct Node
{
int l,r,sum;
}node[N*];//nlogn
int cnt;
int a[N],root[N];
void Insert(int l,int r,int pre,int& now,int val)
{
node[++cnt]=node[pre];
now=cnt;
node[now].sum++;
if(l==r)return;
int m=(l+r)>>;
if(val<=m)Insert(l,m,node[pre].l,node[now].l,val);
else Insert(m+,r,node[pre].r,node[now].r,val);
}
int query(int L,int R,int l,int r,int k)
{
if(node[R].sum-node[L].sum==)return -;
if(l==r)return l<k?l:-;
int m=(l+r)>>;
if(k<=m+||node[node[R].r].sum-node[node[L].r].sum==)return query(node[L].l,node[R].l,l,m,k);
int t=query(node[L].r,node[R].r,m+,r,k);
if(t!=-)return t;
return query(node[L].l,node[R].l,l,m,k);
}
int n,k;
int pos[N],dp[N];
int solve(int i)
{
if(dp[i]!=-)return dp[i];
int l=max(,pos[i]-k);
int r=min(n,pos[i]+k);
int res=query(root[l-],root[r],,n,i);
if(res==-)return dp[i]=;
return dp[i]=solve(res)+;
}
int main() {
ios::sync_with_stdio(false);
cin.tie();
cout.tie();
int T;
cin>>T;
while (T--) {
cnt=;
memset(dp,-, sizeof(dp));
memset(node,, sizeof(node));
cin >> n >> k;
for (int i = ; i <= n; i++) {
cin >> a[i];
pos[a[i]]=i;
}
for (int i = ; i <= n; i++) {
Insert(, n, root[i - ], root[i], a[i]);
}
for(int i=;i<=n;i++)
{
solve(i);
cout<<dp[i]<<(i==n?'\n':' ');
}
}
return ;
}

2019ICPC南京网络赛F Greedy Sequence的更多相关文章

  1. 2019 ICPC 南京网络赛 F Greedy Sequence

    You're given a permutation aa of length nn (1 \le n \le 10^51≤n≤105). For each i \in [1,n]i∈[1,n], c ...

  2. 2019icpc南京网络赛 F 主席树

    题意 给一个\(n\)的全排列数组\(a\),求一个递推数组每一项的值:\(ans[i]=ans[j]+1\),\(j\)为\(a[pos[i]-k]到a[pos[i]+k],(pos[i]为i在数组 ...

  3. 2019ICPC南京网络赛A题 The beautiful values of the palace(三维偏序)

    2019ICPC南京网络赛A题 The beautiful values of the palace https://nanti.jisuanke.com/t/41298 Here is a squa ...

  4. 2019icpc南京网络赛

    B. super_log(扩展欧拉函数) 题意:求aa...(b个a)模M的值. 思路:递归用欧拉函数求解,我们知道欧拉降幂公式: 如果讨论b和φ(p)的关系会很麻烦,网上证明了一种精妙的方法,只需重 ...

  5. The Preliminary Contest for ICPC Asia Nanjing 2019ICPC南京网络赛

    B.super_log (欧拉降幂) •题意 定一个一个运算log*,迭代表达式为 给定一个a,b计算直到迭代结果>=b时,最小的x,输出对m取余后的值 •思路 $log*_{a}(1)=1+l ...

  6. 2019 ICPC南京网络赛 F题 Greedy Sequence(贪心+递推)

    计蒜客题目链接:https://nanti.jisuanke.com/t/41303 题目:给你一个序列a,你可以从其中选取元素,构建n个串,每个串的长度为n,构造的si串要满足以下条件, 1. si ...

  7. 2019icpc南京网络赛_F_Greedy Sequence

    题意 题意不明,队友告诉我对于每个\(i\),所在下标\(p[i]\),在\([p[i]-k,p[i]+k]\)中找到小于\(i\)的最大数\(x\),然后\(ans[i]=ans[x]+1\)即可. ...

  8. 2019ICPC南京网络赛B super_log——扩展欧拉定理

    题目 设函数 $$log_a*(x) = \begin{cases}-1, & \text{ if } x < 1 \\ 1+log_a*(log_ax) & \text{ if ...

  9. 2019ICPC南京网络赛总结

    这次是在学校打的,总体不算好,过两题校排200多..很惨. 开场一段时间没人过题,但是很多人交I, 我也就再看,看着看着发现不可做,这时候转F,花了半天读懂题意的时候想到主席树查找.但是主席树这种查找 ...

随机推荐

  1. InnoDB B树 锁

    InnoDB B树 叶子=>主键+数记录非叶子=>主键1+主键3...主键4 事务和行锁 索引项加锁 相等条件来访问更新数据,避免使用范围条件 (1)InnoDB的行销是基于索引实现的,如 ...

  2. Alibaba-技术专区-开源项目之TransmittableThreadLocal

    1.简介 TransmittableThreadLocal 是Alibaba开源的.用于解决 “在使用线程池等会缓存线程的组件情况下传递ThreadLocal” 问题的 InheritableThre ...

  3. OC开发系列-内存管理

    概述 移动设备的内存极其有限,每个app所有占用的内存是有限的.当app所占用的内存比较多时,系统会发出内存警告,这时得回收一些不需要再使用的内存空间. 任何集成了NSObject的对象都需要手动进行 ...

  4. JNI intArray

    JNIDemo.java public class JNIDemo { static { /* 1. load */ System.loadLibrary("native"); / ...

  5. js两个数组去重后,绑定控件,并支持模糊搜索数组项以及数组互移

    设计大概是这个样子的,很简单,两个div,两个互移按钮,一个搜索框,要求搜索框输入时,触发待选框的搜索项 <input class="form-control" placeh ...

  6. JavaScript代码/ES6语法笔记一

    1. new Set()/去重一个数组 let arr = [1, 2, 2, 3, 3]; let set = new Set(arr); let newArr = Array.from(set); ...

  7. linux的锁比较

      spinlock spinlock介绍 spinlock又称自旋锁,线程通过busy-wait-loop的方式来获取锁,任时刻只有一个线程能够获得锁,其他线程忙等待直到获得锁.spinlock在多 ...

  8. ANdroid手机屏幕反横向等参数设定

    经过我一番百度和看Android文档,我才发现,Android对旋转屏,特别是只有横屏或者竖屏虽重力旋转的支持是到Android4.3.1才有完美支持的 unspecified - 默认值,由系统选择 ...

  9. 在AndroidStudio2.3.2下JNI开发的详细步骤(转)

    转自:http://blog.csdn.net/luhaoying1111/article/details/72468867 安装NDK 在工具栏点击File->Settings->App ...

  10. java序列化对象为什么要定义serialversionUID值?

    SerialVersionUid,简言之,其目的是序列化对象版本控制,有关各版本反序列化时是否兼容.如果在新版本中这个值修改了,新版本就不兼容旧版本,反序列化时会抛出InvalidClassExcep ...