Cod sursa(job #1701454)

Utilizator mihai995mihai995 mihai995 Data 13 mai 2016 09:34:11
Problema Hotel Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 3.33 kb
#include <fstream>
#include <iostream>
using namespace std;

const int N = 1 << 17;

template<class Node, Node (*comp)(Node, Node), class Lazy, Node (*apply)(Node, int, int, Lazy), Lazy (*comp_lazy)(Lazy, Lazy)>
class Aint{
    Node aint[4 * N], n_zero, acc;
    Lazy lz[2 * N], l_zero;

    void lazy_update(int pos, int st, int dr, Lazy L){
    	if ( st == dr )
    		aint[pos] = apply( aint[pos], st, dr, L);
    	else
    		lz[pos] = comp_lazy( lz[pos], L );
    }
    inline Node arbint(int pos, int st, int dr){
    	if ( st == dr ) return aint[pos];
    	aint[pos] = apply(aint[pos], st, dr, lz[pos]);
	int m = (st + dr) >> 1;
	lazy_update( 2 * pos,     st,    m,  lz[pos] );
	lazy_update( 2 * pos + 1, m + 1, dr, lz[pos] );
	lz[pos] = l_zero;
	return aint[pos];
    }
    void update(int pos, int st, int dr, int x, int y, Lazy L){
    	if ( x <= st && dr <= y )
    		return lazy_update(pos, st, dr, L);
	arbint(pos, st, dr);
	int m = (st + dr) >> 1;
	if ( x <= m )
		update(2 * pos,     st,    m,  x, y, L);
	if ( m < y )
		update(2 * pos + 1, m + 1, dr, x, y, L);
	aint[pos] = comp( arbint(2 * pos, st, m), arbint(2 * pos + 1, m + 1, dr) );
    }
    void query(int pos, int st, int dr, int x, int y){
    	arbint(pos, st, dr);
    	if ( x <= st && dr <= y ){
    		acc = comp( acc, aint[pos] );
    		return;
    	}
    	int m = (st + dr) >> 1;
    	if ( x <= m )
    		query(2 * pos,     st,    m,  x, y);
    	if ( m < y )
    		query(2 * pos + 1, m + 1, dr, x, y);
    }
public:
    Aint(Node n_zero, Lazy l_zero) : n_zero(n_zero), l_zero(l_zero) {
    	for (int i = 0; i < 2 * N; i++) aint[i] = n_zero;
    	for (int i = 0; i < N; i++) lz[i] = l_zero;
    }
    void update(int x, int y, Lazy L){
    	return update(1, 1, N, x, y, L);
    }
    void update(int x, Lazy L){
    	return update(x, x, L);
    }
    Node query(int x, int y){
    	acc = n_zero;
    	query(1, 1, N, x, y);
    	return acc;
    }
    pair<int, Node> greedy(Node target, bool (*cmp)(Node, Node)){
    	if ( cmp(aint[1], target) )
    		return make_pair( N, arbint(1, 1, N) );
    	int pos = 1, st = 1, dr = N;
	Node ans = n_zero;
    	while (st != dr){
    		int m = (st + dr) >> 1;
    		pos <<= 1;
    		Node part = comp( ans, arbint(pos, st, m) );
    		if ( cmp(part, target) ){
    			ans = part;
    			st = m + 1;
    			pos++;
    		} else
    			dr = m;
    	}
    	return make_pair(st - 1, ans);
    }
};

struct Node{
	int S, C, D;
	bool T;
	Node (int S = 0, int C = 0, int D = 0, bool T = 0) : S(S), C(C), D(D), T(T) {};
};

inline int max(int a, int b, int c){
	return max( a, max(b, c) );
}

Node combine(Node a, Node b){
	return Node( (a.T ? a.C + b.S : a.S), max(a.C, b.C, a.D + b.S), (b.T ? a.D + b.C : b.D), a.T && b.T );
}

char ovrw(char a, char b){
	return b ? b : a;
}
Node apply(Node n, int x, int y, char upd){
	if ( upd == -1 )
		return Node(0, 0, 0, false);
	if ( upd == 0 )
		return n;
	int a = y - x + 1;
	return Node(a, a, a, true);
}

Aint<Node, combine, char, apply, ovrw> A( Node(0, 0, 0, true), 0);

int main(){
    int n, times, tip, x, y;
    ifstream in("hotel.in");
    ofstream out("hotel.out");

    in >> n >> times;
    A.update(1, n, 1);
    A.update(n + 1, N, -1);
    while (times--){
    	in >> tip;
    	if ( tip == 3 ){
    		out << A.query(1, n).C << '\n';
    		continue;
    	}
    	in >> x >> y;
    	A.update(x, x + y - 1, tip == 1 ? -1 : 1);
    }

    return 0;
}