• [CF1373G] Pawns


    [题目链接]

    http://codeforces.com/contest/1373/problem/G

    [题解]

    首先不妨求出对于每个棋子其所能到达的最近的列 (a_{i} = y_{i} + |x_{i} - k|)

    建立二分图模型 , 将 (i)([a_{i} , s]) 内的点连边。

    根据 (Hall) 定理 , (s) 合法当且仅当对于任意 (j) 满足 ([j , s]) 区间内的和 (leq s - j + 1)

    如果令 ([j , s]) 内的和为 (p_{j}) , 要求的是 (p_{j} + j - 1 leq s)

    线段树维护区间最值即可。

    时间复杂度 : (O(NlogN))

    [代码]

    #include<bits/stdc++.h>
    
    using namespace std;
    
    typedef long long LL;
    
    typedef pair < int , int > pii;
    
    #define rep(i , l , r) for (int i = (l); i < (r); ++i)
    #define mp make_pair
    
    const int MN = 2e6 + 5 , INF = 2e9;
    
    int N , M , K , mx[MN << 2] , tg[MN << 2] , cnt[MN];
    multiset < int > s;
    map < pii , int > st;
    
    
    inline void pushup(int now) {
    	mx[now] = max(mx[now << 1] , mx[now << 1 | 1]);
    }
    inline void build(int now , int l , int r) {
    	if (l == r) {
    		mx[now] = l - 1;
    		return;
    	}
    	int mid = l + r >> 1;
    	build(now << 1 , l , mid) , build(now << 1 | 1 , mid + 1 , r);
    	pushup(now);
    	assert(mx[now] == r - 1);
    } 
    inline void pushdown(int now) {
    	mx[now << 1] += tg[now] , mx[now << 1 | 1] += tg[now];
    	tg[now << 1] += tg[now] , tg[now << 1 | 1] += tg[now];
    	tg[now] = 0; return;
    }
    inline void modify(int now , int l , int r , int ql , int qr , int val) {
    	if (l != r) pushdown(now);
    	if (l == ql && r == qr) {
    		mx[now] += val; tg[now] += val;
    		return;
    	}
    	int mid = l + r >> 1;
    	if (mid >= qr) modify(now << 1 , l , mid , ql , qr , val);
    	else if (mid + 1 <= ql) modify(now << 1 | 1 , mid + 1 , r , ql , qr , val);
    	else modify(now << 1 , l , mid , ql , mid , val) , modify(now << 1 | 1 , mid + 1 , r , mid + 1 , qr , val);
    	pushup(now);
    }
    inline int query(int now , int l , int r , int ql , int qr) {
    	if (ql > qr) return 0;
    	if (l == ql && r == qr) return mx[now];
    	int mid = l + r >> 1; pushdown(now);
    	if (mid >= qr) return query(now << 1 , l , mid , ql , qr);
    	else if (mid + 1 <= ql) return query(now << 1 | 1, mid + 1 , r , ql , qr);
    	else return max(query(now << 1 , l , mid , ql , mid) , query(now << 1 | 1 , mid + 1 , r , mid + 1 , qr));
    }
    int main() {
    	 
    	 scanf("%d%d%d" , &N , &K , &M); build(1 , 1 , 2 * N);
    	 s.insert(N);
    	 for (int i = 1; i <= M; ++i) {
    	 	 int x , y; scanf("%d%d" , &x , &y);
    	 	 int val = 1 , a = y + abs(x - K);
    	 	 if (st[mp(x , y)]) {
    	 	 	 s.erase(s.find(a));
    	 	 	 val = -1; 
    		 } else {
    		 	 s.insert(a);
    		 	 val = 1;
    		 }
    		 st[mp(x , y)] ^= 1;
    		 modify(1 , 1 , 2 * N , 1 , a , val);
    		 printf("%d
    " , query(1 , 1 , 2 * N , 1 , *s.rbegin() + 1) - N);
     	 }
         return 0;
    }
    
  • 相关阅读:
    java 对象属性复制,将一个对象的属性值赋值给另一个对象, 属性名需要相同
    文件上传设置上传文件大小
    layui form.on('select(xxx)',function(){});绑定失败
    列表显示, 内容过长省略显示, 鼠标停留在内容上显示全部内容
    mybatis : ERROR. token : COMMA, pos : 373
    js判断手机系统
    vue v-nav指令属性列表
    第五节 tensorboard可视化
    第四节 生成随机张量和张量合并
    第三节 张量
  • 原文地址:https://www.cnblogs.com/evenbao/p/14437310.html
Copyright © 2020-2023  润新知