zoukankan      html  css  js  c++  java
  • Codeforces 220C

    题意略。

    思路:

    我们可以把 bi[ i ] 在 ai[ ] 中的位置记录下来,然后算出 i - mp[ bi[i] ] ,再将它压入一个multiset。每次我们就二分地来寻找离0最近的数字来作为答案。

    那当我们循环左移的时候怎么办呢?把每个数字都减一,把当前 bi[i] 产生的数字重新赋值再压入吗?

    当然不是,我们可以改变0参考系,也即二分地来寻找离i最近的数字来作为答案。(i从0开始,因为第一个答案相当于循环左移0次)

    那么要删去的那个数字怎么办呢?

    我们将它删去后,压入的值是 (i + n) - mp[ bi[i] ]。可是为什么呢?

    可以认为是    参考系的值 + n - mp[ bi[i] ] (原本应该改成的值)。

    也可以认为是,当前在multiset中的值其实都已经减去了 i ,为了补上这个i,我要在 n - mp[ bi[i] ] 上加上 i。

    详见代码:

    #include<bits/stdc++.h>
    using namespace std;
    const int maxn = 1e5 + 5;
    
    int mp[maxn],bi[maxn],n;
    multiset<int> st;
    
    int main(){
        int n;
        scanf("%d",&n);
        int temp;
        for(int i = 0;i < n;++i){
            scanf("%d",&temp);
            mp[temp] = i;
        }
        for(int i = 0;i < n;++i){
            scanf("%d",&bi[i]);
            st.insert(i - mp[bi[i]]);
        }
        for(int i = 0;i < n;++i){
            multiset<int>::iterator it = st.lower_bound(i);
            int ans = maxn;
            if(it != st.end()) ans = min(ans,(*it) - i);
            if(it != st.begin()) ans = min(ans,i - *(--it));
            printf("%d
    ",ans);
            int t = i - mp[bi[i]];
            st.erase(st.find(t));
            st.insert((i + n) - mp[bi[i]]);
        }
        return 0;
    }
  • 相关阅读:
    USACO Milk2 区间合并
    Codeforces 490B Queue【模拟】
    HDU 3974 Assign the task 简单搜索
    HDU 5119 Happy Matt Friends(2014北京区域赛现场赛H题 裸背包DP)
    Cin、Cout 加快效率方法
    POJ 1159 回文LCS滚动数组优化
    POJ 2479 不相交最大子段和
    POJ 1458 最长公共子序列 LCS
    在阿里最深刻的,还是职场之道给我的震撼
    精细化
  • 原文地址:https://www.cnblogs.com/tiberius/p/9417352.html
Copyright © 2011-2022 走看看