bzoj2093 Frog

Topic Link

Thinking

Very interesting a question.
First consider how to find the K-away position.
Because the sequences given is monotonic, so that the position \ (I \) before \ (K \) away definitely comprising a position \ (I \) length \ (k + 1 \) interval. We \ (l \) represents the left end point of this range, \ (r \) represents the right end point of this range. Then when \ (i + 1 \) when, \ (L \) and \ (R & lt \) will only move to the right. And move the right conditions are \ (r + 1 \) points with \ (i + 1 \) distance than the \ (L \) points to the first \ (i + 1 \) from small dots .
So you can find the first k away each location. Then we get a replacement.
Jump \ (m \) times it is equivalent to the replacement cycle \ (m \) times. Based on the idea of doubling as long as \ (nlogm \) complexity can be completed.

Code

#include<cstdio>
#include<iostream>
using namespace std;
typedef long long ll;
const int N = 1000000 + 100;

ll read() {
    ll x = 0,f = 1;
    char c = getchar();
    while(c < '0' || c > '9') {
        if(c == '-') f = -1;
        c = getchar();
    }
    while(c <= '9' && c >= '0') {
        x = x * 10 + c - '0';
        c = getchar();
    }
    return x * f;
}
ll a[N];
int b[N],n,k;
ll m;
int tmp[N],c[N];
void calc() {
    for(int i = 1;i <= n;++i) c[i] = tmp[i];
    for(int i = 1;i <= n;++i) tmp[i] = c[tmp[i]];
}
int main() {
    n = read(),k = read(),m = read();\
    for(int i = 1;i <= n;++i) a[i] = read();
    int l = 1,r = min(k + 1,n);
    for(int i = 1;i <= n;++i) {
        while((l < i && r < n && a[r + 1] - a[i] < a[i] - a[l]) || r < i) {
            ++l;++r;
        }
        if(a[i] - a[l] >= a[r] - a[i]) tmp[i] = l;
        else tmp[i] = r;
        b[i] = i;
    }
    for(;m;m >>= 1,calc()) {
        if(m & 1) for(int i = 1;i <= n;++i) b[i] = tmp[b[i]];
    }
    
    for(int i = 1;i <= n;++i) 
    printf("%d ",b[i]);
    return 0;
}

Guess you like

Origin www.cnblogs.com/wxyww/p/bzoj2093.html