zoukankan      html  css  js  c++  java
  • [Ynoi2010]iepsmCmq【数据结构】

    传送门

    好久没更博了(

    其实是道 ez 题,但是场上犯蠢就只写了个无脑线段树分治(其实线段树分治比正解还长……不过正解细节略多就是)

    插入的所有元素都可以对 (c) 取模,因此对于 (u+vgeq c)((u, v)),直接取最大的两个元素即可。否则必然有 (u+v< c)

    对每个元素 (u),找到集合中最大的 (v) 使得 (u+v<c),则 (<v) 的元素均不可能与 (u) 组成最优解。如此,可以构造出一张有向图,其中每个元素有唯一的出边。发现这张图上不可能存在长度 (geq 3) 的环,且所有不在任何一个二元环上的边都不可能成为最优解。

    因此只需要维护若干个匹配,每个匹配中的一对元素互为对方的最优解。插入元素时尝试新建匹配,删除元素时等价于将整个匹配删除,然后将其匹配的元素重新插入。发现新建匹配时,拆出来的另一个失配点不会产生新的匹配,因此操作总数是 (O(n)) 级别。上述的集合、匹配、答案等均可以用 STL 维护。

    注意元素互不相等并不表示元素模 (c) 后互不相等,需要特殊维护。

    Code:(时限对 STL 不是特别友好,需要略微卡常)

    #include <bits/stdc++.h>
    #define R register
    #define mp make_pair
    #define ll long long
    #define pii pair<int, int>
    using namespace std;
    
    int n, c, lst;
    multiset<int> s, ans;
    map<int, int> mat;
    
    struct IO {
    //
    static const int N = 1 << 23;
    
    char ibuf[N], obuf[N], *s, *t, w;
    
    IO() : t(obuf) {
    	fread(s = ibuf, 1, N, stdin);
    	return;
    }
    
    ~IO() {
    	fwrite(obuf, 1, t - obuf, stdout);
    	return;
    }
    
    template <class T>
    inline void read(T &x) {
    	x = w = 0;
    	while (!isdigit(*s)) w = (*s == '-'), ++s;
    	while (isdigit(*s)) x = (x << 1) + (x << 3) + (*s ^ 48), ++s;
    	x = w ? -x : x;
    	return;
    }
    
    void print(int x) {
    	if (x < 0) x = -x, *t++ = '-';
    	if (x >= 10) print(x / 10);
    	*t++ = x % 10 + '0';
    	return;
    }
    
    inline void print(char x) {
    	*t++ = x;
    	return;
    }
    //
    } io;
    #define read io.read
    #define print io.print
    
    inline void insrt(int y) {
    	auto w = s.upper_bound(c - y - 1);
    	if (w != s.begin()) {
    		--w;
    		auto z = mat.find(*w);
    		if (z == mat.end() || z->second < y) {
    			if (z != mat.end()) ans.erase(ans.find(*w + z->second)), mat.erase(z->second);
    			ans.insert(y + *w), mat[y] = *w, mat[*w] = y;
    		}
    	}
    	s.insert(y);
    	return;
    }
    
    int main() {
    	int x, y;
    	read(n), read(c);
    	while (n--) {
    		read(x), read(y), y = (y ^ lst) % c;
    		if (x == 1) insrt(y);
    		else {
    			s.erase(s.find(y));
    			if (mat.find(y) != mat.end()) {
    				x = mat[y];
    				mat.erase(y), mat.erase(x);
    				ans.erase(ans.find(y + x));
    				s.erase(s.find(x)), insrt(x);
    			}
    		}
    		if (s.size() < 2) {
    			print('E'), print('E'), print('
    ');
    			lst = 0;
    		}
    		else
    			print(lst = max(ans.size() ? *ans.rbegin() : 0, (*s.rbegin() + *next(s.rbegin())) % c)), print('
    ');
    	}
    	return 0;
    }
    
  • 相关阅读:
    android Json解析详解
    Android 用ping的方法判断当前网络是否可用
    Android 监控网络状态
    Android TableLayout 常用的属性介绍及演示
    三星笔记本R428安装xp win7双系统,切换系统重启才能进入系统解决办法。
    解决Win8不能上网攻略第二版!三步秒杀原驱动
    Android三种实现自定义ProgressBar的方式介绍
    Android应用开发中半透明效果实现方案
    FFT算法的物理意义
    网络编程Socket之TCP之close/shutdown具体解释(续)
  • 原文地址:https://www.cnblogs.com/suwakow/p/12337064.html
Copyright © 2011-2022 走看看