codeforces 220c Little Elephant and Shifts
来源:互联网 发布:ubuntu 14.04 lnmp 编辑:程序博客网 时间:2024/05/18 01:19
很少遇到经典的题目,这个不算经典但是却也非常精彩。题目
题目大意:给定两个两个1-n的排列,定义两个排列的距离为:所有相同数字之间距离的最小值,More formally, it's such minimum|i - j|, that ai = bj.定义Acyclic shift number i (1 ≤ i ≤ n) of permutationb consisting from n elements is a permutationbibi + 1...bnb1b2...bi - 1. Overall a permutation hasn cyclic shifts. 输出者n个cyclic shifts的距离。
eg:
42 1 3 43 4 2 1输出 2 1 0 1
解题思路:由于n很大(10^5),所以,我想到应该是O(nlogn)的算法,我想到线段树,但是怎么也想不出来怎么维护,后来和同学讨论,想到一种方法:第一个序列为A,第二个需要旋转的为B,即使维护B中的值是在A中对应值得左边还是右边,如果是左边,那么旋转之后距离+1,右边则-1,如果我们维护这两个优先队列,当-1的元素-到0时,则插入到左边的序列中,右边的序列删除。对于头上需要移动到最后的元素,则插入操作,和删除操作。说的可能有点乱!
但是有几个难点:1)删除操作怎么处理?优先队列,不管是用堆实现还是stl都没有删除的操作,我的方法是,每一个元素都有一个时间戳,如果出队的元素时间戳过时了,那么直接出对,不用管。这样就达到了删除的作用
2)对于整个优先队列的+1和-1操作,可以考虑使用延迟加减的操作,理解就是,既然整个都+1相当于没有+1,也就是出队的时候在+1就是了,这样的话,插入需要注意了,插入前要加减这个延迟,才能保证出队是的值的正确性。
code:
#include <iostream>#include <stdio.h>#include <string.h>#include <algorithm>#include <queue>#include <stdlib.h>using namespace std;#define N 100010int dat1[N],dat2[N];int pos[N];struct note{ int val,time,index; note(){} note(int _v,int _t,int _i):val(_v),time(_t),index(_i){}};struct cmp{ bool operator() ( note a, note b ) { return a.val > b.val; }};int _time[N];int main(){ int n; while(cin >> n) { for(int i = 0;i < n;i++) scanf("%d",&dat1[i]); for(int i = 0;i < n;i++) scanf("%d",&dat2[i]); for(int i = 0;i < n;i++) pos[dat1[i]] = i; priority_queue < note ,vector<note> ,cmp > l_queue,r_queue; memset(_time,0,sizeof(_time)); for(int i = 0;i < n;i++) { //在原数的左侧 if(pos[ dat2[i] ] >= i) l_queue.push( note(pos[dat2[i]] - i,0, pos[ dat2[i] ] ) ); else r_queue.push( note(i-pos[dat2[i]],0, pos[ dat2[i] ] ) ); } int t = 0; int now_time = 1; for(int i = 0;i < n;i++) { while(l_queue.empty() == 0 && l_queue.top().time != _time[l_queue.top().index]) l_queue.pop(); while(r_queue.empty() == 0 && r_queue.top().time != _time[r_queue.top().index]) r_queue.pop(); if(l_queue.size() == 0) cout << r_queue.top().val - t << "\n"; else if(r_queue.size() == 0) cout << l_queue.top().val + t << "\n"; else cout << min(l_queue.top().val+t,r_queue.top().val-t) << "\n"; if(i == n-1) continue; t++; int ttt = dat2[i]; r_queue.push(note(n-1 - pos[ttt] + t,now_time,pos[ttt] )); _time[pos[ttt]] = now_time++; while(r_queue.empty() == 0 && r_queue.top().val - t == 0) { note tt = r_queue.top();r_queue.pop(); tt.val = 0-t; l_queue.push(tt); } } } return 0;}
ps:我很喜欢这个题~
- codeforces 220c Little Elephant and Shifts
- CF 220C Little Elephant and Shifts
- CF Little Elephant and Shifts
- codeforces 221C Little Elephant and Problem
- Codeforces 220B Little Elephant and Array
- CodeForces 220A Little Elephant and Problem
- CodeForces 220B Little Elephant and Array
- <codeforces>Little Elephant and Sorting
- Codeforces Round #136 (Div. 2) C. Little Elephant and Problem
- Codeforces-258C:Little Elephant and LCM(数论)
- CodeForces Round #136(220B) - Little Elephant and Array
- 线段树 CodeForces 220B - Little Elephant and Array
- Codeforces 220B(Little Elephant and Array)
- Codeforces 220B - Little Elephant and Array 离线树状数组
- Little Elephant and Array - CodeForces 220 B 树状数组
- CodeForces 220B Little Elephant and Array 莫队算法
- <codeforces>A. Little Elephant and Rozdil
- codeforces 204A Little Elephant and Interval
- About ION(innovation in eclectronic trading )
- cookie学习笔记
- Ext扩展饼图组件
- 内核驱动之内核定时器示例
- Boost库的使用和编译
- codeforces 220c Little Elephant and Shifts
- linux 内核地址空间和进程地址空间
- jpa学习笔记
- ssh中“Host key verification failed.“的解决方案
- java使用xfire与spring创建webservice,详细描述示例代码
- poj3041 - Asteroids
- 不唐突的JavaScript的七条准则
- 泛型类和泛型方法
- 利用CStdioFile创建文件并写入文件