zoukankan      html  css  js  c++  java
  • NOIP2017:列队

    Sol

    考场上:
    这不是送(50)吗,(Q^2)递推就好了
    然后,怎么又送(20)分???
    (woc),只有半个小时了,顺利没调出来只有(50)
    考后:
    (TM)一个大于号写成小于号。。。
    (20)分没了
    (TAT)


    正解的一种

    (n)棵线段树维护每一行的前(m-1)
    再开一棵维护最后一列的情况
    长度为(max(n, m)+q)
    动态开点
    每次就变成删除节点,插入节点了
    维护区间元素个数
    查找就是全局第(k)

    # include <bits/stdc++.h>
    # define RG register
    # define IL inline
    # define Fill(a, b) memset(a, b, sizeof(a))
    using namespace std;
    const int _(3e5 + 5);
    typedef long long ll;
    
    IL int Input(){
        RG int x = 0, z = 1; RG char c = getchar();
        for(; c < '0' || c > '9'; c = getchar()) z = c == '-' ? -1 : 1;
        for(; c >= '0' && c <= '9'; c = getchar()) x = (x << 1) + (x << 3) + (c ^ 48);
        return x * z;
    }
    
    int n, m, q, rt[_], num, len, tp, tail[_], now;
    struct Segment{
    	int ls, rs, sz;
    	ll val;
    } T[_ * 40];
    
    IL int Size(RG int l, RG int r){
    	if(now == n + 1){
    		if(r <= n) return r - l + 1;
    		if(l <= n) return n - l + 1;
    		return 0;
    	}
    	if(r < m) return r - l + 1;
    	if(l < m) return m - l;
    	return 0;
    }
    
    IL ll Query(RG int &x, RG int l, RG int r, RG int p){
    	if(!x) x = ++num, T[x].sz = Size(l, r);
    	--T[x].sz;
    	if(l == r){
    		if(!T[x].val) T[x].val = (now == n + 1) ? 1LL * l * m : 1LL * (now - 1) * m + l;
    		return T[x].val;
    	}
    	RG int mid = (l + r) >> 1, sz = T[x].ls ? T[T[x].ls].sz : Size(l, mid);
    	if(p <= sz) return Query(T[x].ls, l, mid, p);
    	return Query(T[x].rs, mid + 1, r, p - sz);
    }
    
    IL void Modify(RG int &x, RG int l, RG int r, RG int p, RG ll v){
    	if(!x) x = ++num, T[x].sz = Size(l, r);
    	++T[x].sz;
    	if(l == r){
    		T[x].sz = 1, T[x].val = v;
    		return;
    	}
    	RG int mid = (l + r) >> 1;
    	if(p <= mid) Modify(T[x].ls, l, mid, p, v);
    	else Modify(T[x].rs, mid + 1, r, p, v);
    }
    
    int main(RG int argc, RG char* argv[]){
    	n = Input(), m = Input(), q = Input(), len = max(n, m) + q;
    	for(RG int i = 1; i <= n; ++i) T[rt[i] = ++num].sz = tail[i] = m - 1;
    	T[rt[n + 1] = ++num].sz = tail[n + 1] = n;
    	for(RG int i = 1; i <= q; ++i){
    		RG int x = Input(), y = Input(); RG ll id1, id2;
    		if(y == m){
    			now = n + 1, id1 = Query(rt[n + 1], 1, len, x);
    			++tail[n + 1], Modify(rt[n + 1], 1, len, tail[n + 1], id1);
    		}
    		else{
    			now = x, id1 = Query(rt[x], 1, len, y);
    			++tail[now = n + 1], Modify(rt[n + 1], 1, len, tail[n + 1], id1);
    			id2 = Query(rt[n + 1], 1, len, x);
    			++tail[now = x], Modify(rt[x], 1, len, tail[x], id2);
    		}
    		printf("%lld
    ", id1);
    	}
        return 0;
    }
    
  • 相关阅读:
    SqlServer数据库正在还原的解决办法
    v-表单自动收集信息
    v-按键修饰符
    v-for列表排序
    class与style的绑定
    v计算属性的应用
    v子向父组件传值
    v传值和传引用
    v-父组件向子组件传值
    练习鼠标悬停切换图片页面
  • 原文地址:https://www.cnblogs.com/cjoieryl/p/8676076.html
Copyright © 2011-2022 走看看