Submission #20398

#TimeUsernameProblemLanguageResultExecution timeMemory
20398admin초음속철도 (OJUZ11_rail)C++11
100 / 100
943 ms25176 KiB
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <memory.h>
#include <math.h>
#include <assert.h>
#include <stack>
#include <queue>
#include <map>
#include <set>
#include <algorithm>
#include <string>
#include <functional>
#include <vector>
#include <deque>
#include <utility>
#include <bitset>
#include <limits.h>
#include <time.h>
#include <functional>
#include <numeric>
 
using namespace std;
typedef long long ll;
typedef unsigned long long llu;
typedef double lf;
typedef unsigned int uint;
typedef long double llf;
typedef pair<int, int> pii;
typedef pair<ll, int> pli;
 
#define debug(format, ...) printf(format, __VA_ARGS__);
 
const int M_ = 200500;
const int MAX_TREE_SIZE = 1<<20;
 
const int MOD = (ll)1e9 + 7;
 
class modint {
	int v;
public:
	modint (): v(0) { }
	modint (ll v): v((v + MOD) % MOD) { }
 
	bool operator== (modint x) { return v == x.v; }
	bool operator!= (modint x) { return v != x.v; }
 
	modint operator+ (modint x) { return v + x.v; }
	modint operator- (modint x) { return v - x.v; }
	modint operator* (modint x) { return (ll)v * x.v; }
 
	modint& operator+= (const modint x) { return *this = (*this + x); }
	modint& operator-= (const modint x) { return *this = (*this - x); }
	modint& operator*= (const modint x) { return *this = (*this * x); }
 
	int operator* () { return v; }
};
 
int F, N, M;
vector< pair<int, int> > intervals;
vector< int* > renum;
 
// 서브태스크:
//	1. n, m <= 20
//	2. n <= 20 (합쳐서 10점)
//	3. n <= 1000, m <= 1000
//	4. 포함 관계
//	5. n <= 500000, m <= 500000
 
namespace segtree {
	struct node {
		modint sum, mul, add;
		node(modint sum = 0, modint mul = 1, modint add = 0): sum(sum), mul(mul), add(add) { }
	};
 
	vector<node> tree(MAX_TREE_SIZE + 1);
 
	void spread (int idx, int nl, int nr) {
		node& nd = tree[idx];
		node& c1 = (nl == nr) ? tree[0] : tree[idx * 2];
		node& c2 = (nl == nr) ? tree[0] : tree[idx * 2 + 1];
 
		if(nd.mul != 1) {
			nd.sum *= nd.mul;
			for(auto &child : {&c1, &c2}) {
				child->mul *= nd.mul;
				child->add *= nd.mul;
			}
			nd.mul = 1;
		}
 
		if(nd.add != 0) {
			nd.sum += nd.add * (nr - nl + 1);
			for(auto &child : {&c1, &c2}) {
				child->add += nd.add;
			}
			nd.add = 0;
		}
	}
 
	modint update (int idx, int nl, int nr, int l, int r, char type, modint v) {
		if(l > r) return 0;
		node &nd = tree[idx];
		spread(idx, nl, nr);
		if(l <= nl && nr <= r) {
			(type == '*' ? nd.mul : nd.add) = v;
			spread(idx, nl, nr);
			return nd.sum;
		}
		int nm = (nl + nr) >> 1;
		nd.sum = 0;
		if(l <= nm) nd.sum += update(idx*2,	 nl, nm,	 l, min(nm, r),	 type, v);
		if(r >	nm) nd.sum += update(idx*2+1, nm+1, nr, max(nm+1, l), r, type, v);
		return nd.sum;
	}
 
	void multiply(int l, int r, modint v) {
		update(1, 0, N, l, r, '*', v);
	}
 
	void add (int l, int r, modint v) {
		update(1, 0, N, l, r, '+', v);
	}
 
	modint get (int idx, int nl, int nr, int x) {
		spread(idx, nl, nr);
		if(nl == nr) return tree[idx].sum;
		int nm = (nl + nr) >> 1;
		return (x <= nm) ?
								get(idx*2,	 nl, nm,	 x) :
								get(idx*2+1, nm+1, nr, x);
	}
 
	modint get(int x) {
		return get(1, 0, N, x);
	}
};
 
modint ans;
 
int main() {
	assert(scanf("%d%d", &N, &M) == 2);
  while(M > 200000);
	intervals.resize(M);
	renum.reserve(2*M);
	for(auto &interval : intervals) {
		assert(scanf("%d%d", &interval.first, &interval.second) == 2);
		assert(1 <= interval.first && interval.first < interval.second && interval.second <= N);
		renum.push_back(&interval.first);
		renum.push_back(&interval.second);
	}
	F = 1;
	renum.push_back(&F);
	renum.push_back(&N);
 
 
	sort(renum.begin(), renum.end(), [&](const int *a, const int *b){
		return *a < *b;
	});
 
	for(int i = 0, k = 0; i < renum.size(); ) {
		int j = i, v = *renum[i];
		k += 1;
		for(; j < renum.size() && *renum[j] == v; j++) *renum[j] = k;
		i = j;
	}
 
	for(auto &interval : intervals) {
		interval.second -= 1;
	}
	sort(intervals.begin(), intervals.end());
	N -= 1;
 
	segtree::add(0, 0, 1);
	for(auto &interval : intervals) {
		int l, r; tie(l, r) = interval;
		modint v = segtree::get(l-1);
		segtree::multiply(0, l-1, 2);
		segtree::add(l, r, v);
		segtree::multiply(r+1, N, 2);
	}
 
	ans = segtree::get(N);
	printf("%d\n", *ans);
	return 0;
}

Compilation message (stderr)

rail.cpp: In function 'int main()':
rail.cpp:161:26: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
  for(int i = 0, k = 0; i < renum.size(); ) {
                          ^
rail.cpp:164:11: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
   for(; j < renum.size() && *renum[j] == v; j++) *renum[j] = k;
           ^
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...