• @codeforces



    @description@

    我们称一个序列是 k-d 的,当且仅当我们可以加入最多 k 个数,然后将序列排序,最终得到的序列是等差的且公差为 d。

    给定一个序列 a,求 a 中的一个最长子区间,使得该子区间是 k-d 的。

    1 ≤ n ≤ 2·10^5; 0 ≤ k ≤ 2·10^5; 0 ≤ d ≤ 10^9; -10^9 ≤ ai ≤ 10^9。

    原题戳这里

    @solution@

    先特判 d = 0 的情况:找最长连续相同的段。

    假如一个区间能够加入若干数使其满足条件,则这个区间内的所有数 mod d 应相等。其次,这个区间还应满足任意两个数互不相等。
    可以求出每一个点 i 作为右端点,满足以上两个条件的左端点最远到 le[i]。

    对于满足以上两个条件的区间,我们尝试去求所需要加入的数最少为多少。
    求出该区间 [l, r] 的 max 与 min,则 (max - min) / d 为它的最少项数。现在已经有 r - l + 1 项,则最少需要 (max - min) / d - (r - l + 1) 项。

    注意 (max - min) / d 可以写成 (max - max mod d) / d - (min - min mod d) / d。
    扫描右端点,通过单调队列可以 O(n) 修改得到每个左端点对应的 max 与 min,在线段树上存储一下每个左端点 (max - max mod d) / d - (min - min mod d) / d + l - 1 的值。
    查询时只需要在 [le[i], i] 中线段树二分找最左边的 <= r 的值。

    时间复杂度 O(nlogn)。

    @accepted code@

    #include <map>
    #include <stack>
    #include <cstdio>
    #include <iostream>
    #include <algorithm>
    using namespace std;
    
    #define mp make_pair
    #define fi first
    #define se second
    typedef pair<int, int> pii;
    typedef long long ll;
    
    const int MAXN = 200000;
    const ll INF = ll(1E15);
    
    struct segtree{
    	#define lch (x<<1)
    	#define rch (x<<1|1)
    	struct node{
    		int le, ri;
    		ll mn, tg;
    	}t[4*MAXN + 5];
    	void pushup(int x) {
    		t[x].mn = min(t[x<<1].mn, t[x<<1|1].mn);
    	}
    	void build(int x, int l, int r) {
    		t[x].le = l, t[x].ri = r, t[x].tg = 0;
    		if( l == r ) {
    			t[x].mn = l;
    			return ;
    		}
    		int m = (l + r) >> 1;
    		build(lch, l, m), build(rch, m + 1, r);
    		pushup(x);
    	}
    	void update(int x, ll k) {
    		t[x].mn += k, t[x].tg += k;
    	}
    	void pushdown(int x) {
    		if( t[x].tg ) {
    			update(lch, t[x].tg), update(rch, t[x].tg);
    			t[x].tg = 0;
    		}
    	}
    	void modify(int x, int l, int r, ll d) {
    		if( l > t[x].ri || t[x].le > r )
    			return ;
    		if( l <= t[x].le && t[x].ri <= r ) {
    			update(x, d);
    			return ;
    		}
    		pushdown(x);
    		modify(lch, l, r, d);
    		modify(rch, l, r, d);
    		pushup(x);
    	}
    	int query(int x, int k) {
    		if( t[x].le == t[x].ri ) return t[x].le;
    		pushdown(x);
    		if( t[lch].mn <= k ) return query(lch, k);
    		else return query(rch, k);
    	}
    }T;
    
    map<int, int>lst;
    int a[MAXN + 5], b[MAXN + 5], r[MAXN + 5];
    stack<pii>s1, s2;
    int main() {
    	int n, k, d; scanf("%d%d%d", &n, &k, &d);
    	for(int i=1;i<=n;i++) scanf("%d", &a[i]);
    	if( d == 0 ) {
    		int ansl = 1, ansr = 1, le = 1;
    		for(int i=2;i<=n;i++) {
    			if( a[i] != a[le] ) le = i;
    			if( i - le > ansr - ansl )
    				ansl = le, ansr = i;
    		}
    		printf("%d %d
    ", ansl, ansr);
    	}
    	else {
    		for(int i=1;i<=n;i++)
    			r[i] = (a[i] % d + d) % d, b[i] = (a[i] - r[i]) / d;
    		int ansl = 1, ansr = 1, le = 1;
    		T.build(1, 1, n), T.update(1, -k);
    		s1.push(mp(1, 1)), s2.push(mp(1, 1));
    		lst[a[1]] = 1;
    		for(int i=2;i<=n;i++) {
    			pii p = mp(i, i);
    			while( !s1.empty() && b[s1.top().se] < b[i] ) {
    				p = mp(s1.top().fi, i);
    				T.modify(1, s1.top().fi, s1.top().se, -b[s1.top().se]), s1.pop();
    			}
    			T.modify(1, p.fi, p.se, b[p.se]), s1.push(p);
    			p = mp(i, i);
    			while( !s2.empty() && b[s2.top().se] > b[i] ) {
    				p = mp(s2.top().fi, i);
    				T.modify(1, s2.top().fi, s2.top().se, b[s2.top().se]), s2.pop();
    			}
    			T.modify(1, p.fi, p.se, -b[p.se]), s2.push(p);
    			if( r[i] != r[i-1] )
    				T.modify(1, le, i - 1, INF), le = i;
    			int x = lst[a[i]] + 1;
    			if( le < x )
    				T.modify(1, le, x - 1, INF), le = x;
    			lst[a[i]] = i;
    			int j = T.query(1, i);
    			if( i - j > ansr - ansl )
    				ansl = j, ansr = i;
    		}
    		printf("%d %d
    ", ansl, ansr);
    	}
    }
    /*
    r - l + 1 + k >= max - min + 1
    
    r >= max - min + l - k
    */
    

    @details@

    感觉难度系数评到 3100 是不是太高了。。。
    毕竟我都会做的题。

  • 相关阅读:
    微信公众平台—— 获取微信服务器IP地址
    微信公众平台——获取access_token、expires_in
    PHP版本切换
    开源各种系统
    VUE -- 如何快速的写出一个Vue的icon组件?
    Mac下php 5升级到php 7的步骤详解
    Nginx反向代理导致PHP获取不到正确的HTTP_HOST,SERVER_NAME,客户端IP的解决方法
    nginx服务器URL无法自动添加index.php
    php类库安装xml simplexml
    Mac DBeaver Client home is not specified for connection解决办法
  • 原文地址:https://www.cnblogs.com/Tiw-Air-OAO/p/12020571.html
Copyright © 2020-2023  润新知