• 「UOJ218」火车管理


    「UOJ218」火车管理

    解题思路:观察发现,在弹出 (x) 之前,它前面这个元素都是保持不变的,所以可以用一棵可持久化线段树维护每一个栈顶元素的插入时间,每次找到当前时间(-1) 的版本就可以查到栈顶,另外用一棵线段树维护区间答案即可,复杂度 (O(mlog n))

    /*program by mangoyang*/
    #include <bits/stdc++.h>
    #define inf (0x7f7f7f7f)
    #define Max(a, b) ((a) > (b) ? (a) : (b))
    #define Min(a, b) ((a) < (b) ? (a) : (b))
    typedef long long ll;
    using namespace std;
    template <class T>
    inline void read(T &x){
    	int ch = 0, f = 0; x = 0;
    	for(; !isdigit(ch); ch = getchar()) if(ch == '-') f = 1;
    	for(; isdigit(ch); ch = getchar()) x = x * 10 + ch - 48;
    	if(f) x = -x;
    }
    const int N = 500005;
    int q[N], rt[N], n, m, ty, tim, op, l, r, x; 
    #define fi first
    #define se second
    inline pair<int, int> chkmax(pair<int, int> A, pair<int, int> B){
    	return A.fi > B.fi ? A : B;
    }
    #define mid ((l + r) >> 1)
    namespace Tim{
    	int lc[N*25*25], rc[N*25*25], size; pair<int, int> tag[N*25*25];
    	inline int copynode(int x){
    		return lc[++size] = lc[x], rc[size] = rc[x], tag[size] = tag[x], size;
    	}
    	inline void ins(int &u, int pr, int l, int r, int L, int R, pair<int, int> x){
    		u = copynode(pr);
    		if(l >= L && r <= R) return (void) (tag[u] = x);
    		if(L <= mid) ins(lc[u], lc[pr], l, mid, L, R, x);
    		if(mid < R) ins(rc[u], rc[pr], mid + 1, r, L, R, x);
    	}
    	inline pair<int, int> query(int u, int l, int r, int pos){
    		if(l == r) return tag[u];
    		if(pos <= mid) return chkmax(tag[u], query(lc[u], l, mid, pos));
    		else return chkmax(tag[u], query(rc[u], mid + 1, r, pos));
    	}
    }	
    namespace Seg{
    	#define lson (u << 1)
    	#define rson (u << 1 | 1)
    	int s[N<<2], tag[N<<2];
    	inline void pushdown(int u, int l, int r){
    		if(!tag[u]) return;
    		s[lson] = (mid - l + 1) * tag[u], tag[lson] = tag[u];
    		s[rson] = (r - mid) * tag[u], tag[rson] = tag[u], tag[u] = 0;
    	}
    	inline void change(int u, int l, int r, int L, int R, int x){
    		if(l >= L && r <= R) return (void) (tag[u] = x, s[u] = (r - l + 1) * x);
    		pushdown(u, l, r);
    		if(L <= mid) change(lson, l, mid, L, R, x);
    		if(mid < R) change(rson, mid + 1, r, L, R, x);
    		s[u] = s[lson] + s[rson];
    	}
    	inline int query(int u, int l, int r, int L, int R){
    		if(l >= L && r <= R) return s[u];
    		int res = 0; pushdown(u, l, r);
    		if(L <= mid) res += query(lson, l, mid, L, R);
    		if(mid < R) res += query(rson, mid + 1, r, L, R);
    		return res;
    	}
    
    }
    int main(){
    	read(n), read(m), read(ty); int lastans = 0;
    	while(m--){
    		read(op);
    		if(op == 1){
    			read(l), read(r);
    			l = (l + lastans * ty) % n + 1, r = (r + lastans * ty) % n + 1;
    			if(l > r) swap(l, r);
    			printf("%d
    ", lastans = Seg::query(1, 1, n, l, r));
    		}
    		if(op == 2){
    			read(l), l = (l + lastans * ty) % n + 1;
    			pair<int, int> now = Tim::query(rt[tim], 1, n, l);
    			if(!now.se) continue;
    			pair<int, int> tmp = Tim::query(rt[now.se-1], 1, n, l);
    			Seg::change(1, 1, n, l, l, q[tmp.se]);
    			++tim;
    			Tim::ins(rt[tim], rt[tim-1], 1, n, l, l, make_pair(tim, tmp.se));
    		}
    		if(op == 3){
    			read(l), read(r), read(x);
    			l = (l + lastans * ty) % n + 1, r = (r + lastans * ty) % n + 1;
    			if(l > r) swap(l, r);
    			q[++tim] = x;
    			Seg::change(1, 1, n, l, r, q[tim]);
    			Tim::ins(rt[tim], rt[tim-1], 1, n, l, r, make_pair(tim, tim));
    		}
    	}
    	return 0;
    }
    
  • 相关阅读:
    myeclipse16怎么去掉项目中的CodeLive Panel?
    JTable动态刷新数据
    javaEE中config.properties文件乱码解决办法
    ZipUtil
    uri中为什么本地文件file后面跟三个斜杠, http等协议跟两个斜杠?
    Java中Access restriction:····的解决方法
    libGDX开发环境搭建-Android Studio 最新版
    mxnet反序列化: 由symbol到gluon
    mxnet symbol reshape用法
    Hybrid
  • 原文地址:https://www.cnblogs.com/mangoyang/p/10414711.html
Copyright © 2020-2023  润新知