2019ICPC Nanjing network game F Greedy Sequence

The meaning of problems: For 1 <= i <= n each found (pos [i] -k, pos [i] + k) is not greater than the maximum number i of the inner, ans [i] = ans [mx] +1, If ans [mx] unknown recursively process ans [mx]

PS: write k precursor Chairman tree when pruning the title race is not a T, but the lab students n ^ 2 had autistic 10w ...

President tree k precursors: In [l, r] to find the maximum value of k is smaller than the range, is essentially a tree with tree pruning Chair dfs

Main ALGORITHM: current interval [l, R & lt] the sum (digits) 0 to prune, when l == r, if l <k k l is the description of the precursor, or precursor described absence of k, find , if k <= m + 1 (m = (l + r) / 2) is not present or the right digital section (digital number is 0), and returns the answer recursion left section (note why m + 1, because when k <= m + 1, the value of k must only be smaller than in the left interval [l, m]), the interval or to find the right, when the right recursive interval solvable, certainly optimal solution directly back this solution can, when the right intervals no solution before the interval left recursively solving

After a series of such pruning, the algorithm can run very fast!

In fact, there is an idea that is half the k-th largest value to ask, this idea is relatively simple and complexity is O (nlogn ^ 2), does not know will not T, trying to make up time on the

AC Code:

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

 

Guess you like

Origin www.cnblogs.com/xusirui/p/11462666.html
Recommended