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号