zoukankan      html  css  js  c++  java
  • Codeforces 1288E Messenger Simulator(BIT)

    题目链接:

    Codeforces 1288E Messenger Simulator

    思路:

    1.对于每个数,它的最小要么是被移到最左边是1,要么就是初始位置;
    2.至于计算最大,贪心的思想是:如果一个数要被移动,我们在移动之前计算一下这个数左边有多少个;同时所有移动结束后也应该计算一下;最大取所有历史计算值的最大值;
    3.如何快速的计算左边有多少个数呢?这种动态前缀和当然是用树状数组,如何模拟往左移的情况呢?我们可以一开始就在bit数组的最左边设m个值为0的点,每次移动就是从右往左填补这m个位置;

    代码:

    #include<bits/stdc++.h>
    
    using namespace std;
    
    const int maxn = 3e5 + 5;
    int n, m, N, a[maxn], bit[maxn << 1];
    int mn[maxn], mx[maxn], pos[maxn];
    #define lowbit(i) (i&-i)
    inline void add(int i, int x){
    	while(i <= N) bit[i] += x, i += lowbit(i);	
    }
    inline int sum(int i){
    	int ans = 0;
    	while(i) ans += bit[i], i -= lowbit(i);
    	return ans;	
    }
    
    int main() {
    #ifdef MyTest
    	freopen("Sakura.txt", "r", stdin);
    #endif	
    	scanf("%d %d", &n, &m);
    	N = n + m;
    	for(int i = 1; i <= m; i++) scanf("%d", a + i);
    	for(int i = 1; i <= n; i++){
    		mn[i] = mx[i] = i;
    		add(i + m, 1);
    		pos[i] = i + m;
    	}
    	for(int i = 1; i <= m; i++){
    		int now = a[i];
    		mn[now] = 1;
    		mx[now] = max(mx[now], sum(pos[now]));
    		add(pos[now], -1);
    		pos[now] = m - i + 1;
    		add(pos[now], 1);
    	}
    	for(int i = 1; i <= n; i++) mx[i] = max(mx[i], sum(pos[i]));
    	for(int i = 1; i <= n; i++) printf("%d %d
    ", mn[i], mx[i]);
    	return 0;
    }
    
  • 相关阅读:
    破周三,前不着村后不着店的,只好学pandas了,你该这么学,No.9
    周一不睡觉,也要把pandas groupy 肝完,你该这么学,No.8
    大周末的不休息,继续学习pandas吧,pandas你该这么学,No.7
    链接
    音乐
    术语
    新闻
    我的文章分类
    我的代码规则
    Jenkins 访问特别慢,且不消耗服务器资源
  • 原文地址:https://www.cnblogs.com/yuhan-blog/p/12308680.html
Copyright © 2011-2022 走看看