Codeforces 221 E. Little Elephant and Shifts(思维题)
The Little Elephant has two permutations a and b of length n, consisting of numbers from 1 to n, inclusive. Let's denote the i-th(1 ≤ i ≤ n) element of the permutation a as ai, the j-th (1 ≤ j ≤ n) element of the permutation b — as bj.
The distance between permutations a and b is the minimum absolute value of the difference between the positions of the occurrences of some number in a and in b. More formally, it's such minimum |i - j|, that ai = bj.
A cyclic shift number i (1 ≤ i ≤ n) of permutation b consisting from n elements is a permutation bibi + 1... bnb1b2... bi - 1. Overall a permutation has n cyclic shifts.
The Little Elephant wonders, for all cyclic shifts of permutation b, what is the distance between the cyclic shift and permutation a?
The first line contains a single integer n (1 ≤ n ≤ 105) — the size of the permutations. The second line contains permutation a as ndistinct numbers from 1 to n, inclusive. The numbers are separated with single spaces. The third line contains permutation b in the same format.
In n lines print n integers — the answers for cyclic shifts. Print the answers to the shifts in the order of the shifts' numeration in permutation b, that is, first for the 1-st cyclic shift, then for the 2-nd, and so on.
2
1 2
2 1
1
0
4
2 1 3 4
3 4 2 1
2
1
0
1
题意:给出一个1——n的排列a,再给出一个1——n的排列b。若a[i]==b[j],则dis=|i-j|
每次将b序列左移1位,移n-1次,序列第一个补到最后面,问初始序列以及每次左移后的序列最小的dis
若b[j]在a[i]的左边,随着每次左移,两点间dis+1
若b[j]在a[i]的右边,随着每次左移,两点间dis-1
可以统计到这一次左移,一共加了多少1,减了多少1,出队入队的时候再考虑这些1,
即延迟标记
每次的答案,从>=0的里面找最小的,<0的里面找最大的,两者再取最小
multiset 模拟每次把第一个挪到最后一个的过程
解释最后一行:n-a[x]是第一个拿到最后一个的实际距离,再加i+1是延迟标记
#include<cstdio> #include<set> #include<algorithm> using namespace std; multiset<int>s; multiset<int>::iterator it; int a[100001],ans,b[100001]; int main() { int n,x; scanf("%d",&n); for(int i=1;i<=n;i++) { scanf("%d",&x); a[x]=i; } for(int i=1;i<=n;i++) { scanf("%d",&b[i]); s.insert(i-a[b[i]]); } for(int i=0;i<n;i++) { it=s.lower_bound(i); ans=1e5+10; if(it!=s.end()) ans=min(ans,*it-i); if(it!=s.begin()) ans=min(ans,i-(*--it)); printf("%d\n",ans); x=b[i+1]; s.erase(s.find(i+1-a[x])); s.insert(i+1-a[x]+n); } }