cf1288 E. Messenger Simulator
题意:
有个联系人列表,当 \(i\) 给你发消息,\(i\) 就会被置顶。现在 \(a[]\) 依次给你发来消息,问每个联系人的历史最高位置和最低位置
思路:
树状数组记录每个位置有没有人
当 \(x\) 发来消息,把 \(x\) 提到最前面。但是怎么提呢?在树状数组的前面留一堆空位就好了!
不用每次都更新所有人的答案,只需要在 \(x\) 发来消息的时候更新 \(x\) 的答案。最后把所有人的再更新一遍。
int n, m, p[N], mn[N], mx[N];//当前位置,最小位置,最大位置
signed main() {
    iofast;
    cin >> n >> m;
    for(int i = 1; i <= n; i++) //初始
        mn[i] = mx[i] = i,
        p[i] = i + m, add(p[i], 1);//前面留m个空位
    for(int i = m; i; i--) { //i就是要放的空位
        int x; cin >> x;
        mn[x] = 1; //更新最小位置
        mx[x] = max(mx[x], ask(p[x])); //更新最大位置
        add(p[x], -1), add(p[x] = i, 1);
    }
    for(int i = 1; i <= n; i++)
        mx[i] = max(mx[i], ask(p[i])),
        cout << mn[i] << ' ' << mx[i] << endl;
}
 
                    
                     
                    
                 
                    
                
 
                
            
         
         浙公网安备 33010602011771号
浙公网安备 33010602011771号