結果
| 問題 | No.801 エレベーター |
| コンテスト | |
| ユーザー |
|
| 提出日時 | 2019-03-20 11:03:12 |
| 言語 | C++17 (gcc 13.3.0 + boost 1.89.0) |
| 結果 |
TLE
|
| 実行時間 | - |
| コード長 | 4,234 bytes |
| 記録 | |
| コンパイル時間 | 2,796 ms |
| コンパイル使用メモリ | 213,704 KB |
| 最終ジャッジ日時 | 2025-01-06 23:37:03 |
|
ジャッジサーバーID (参考情報) |
judge4 / judge2 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| sample | AC * 3 |
| other | AC * 10 TLE * 16 |
ソースコード
#include <bits/stdc++.h>
using namespace std;
const int64_t M = 1'000'000'007;
enum rangeOperaion{
NUL,
UPDATE,
ADD
};
class segTree{
int N;
int64_t e = 0;
struct{
int64_t operator()(int64_t a, int64_t b){
return (a+b) % M;
}
} func;
int64_t *tree;
pair<rangeOperaion, int64_t> *lazy;
const pair<rangeOperaion, int64_t> I=make_pair(NUL, 0);
pair<int, int> *range;
int getParent(int child){
return child/2;
}
pair<int,int> getChildren(int parent){
return make_pair(2*parent, 2*parent+1);
}
int lg(int64_t N){
int lgN;
for(lgN=0;(1<<lgN)<N;lgN++);
return lgN;
}
void setLazy(int pos, pair<rangeOperaion, int64_t> val){
if(val.first==UPDATE) lazy[pos]=val;
else if(lazy[pos].first==NUL) lazy[pos]=val;
else lazy[pos].second+=val.second;
}
void eval(int pos){
if(lazy[pos].first==NUL) return;
if(pos<N){
setLazy(getChildren(pos).first, lazy[pos]);
setLazy(getChildren(pos).second, lazy[pos]);
}
if(lazy[pos].first==UPDATE){
//if(output==SUM)
tree[pos]=lazy[pos].second*(range[pos].second-range[pos].first);
//else tree[pos]=lazy[pos].second;
}else{
//if(output==SUM)
tree[pos]+=lazy[pos].second*(range[pos].second-range[pos].first);
//else tree[pos]+=lazy[pos].second;
}
lazy[pos]=I;
}
void operate(int64_t val, int pos, int left, int right, rangeOperaion op){
eval(pos);
if(right<=range[pos].first || range[pos].second<=left) return;
if(left<=range[pos].first && range[pos].second<=right){
setLazy(pos, make_pair(op, val));
eval(pos);
return;
}
operate(val, getChildren(pos).first, left, right, op);
operate(val, getChildren(pos).second, left, right, op);
tree[pos]=func(tree[getChildren(pos).first], tree[getChildren(pos).second]);
}
int64_t get(int pos, int left, int right){
eval(pos);
if(right<=range[pos].first || range[pos].second<=left) return e;
if(left<=range[pos].first && range[pos].second<=right) return tree[pos];
return func(get(getChildren(pos).first, left, right), get(getChildren(pos).second, left, right));
}
public:
segTree(int n){
N=(1LL<<lg(n));
if(N<n) N*=2;
tree=new int64_t[2*N];
lazy=new pair<rangeOperaion,int64_t>[2*N];
range=new pair<int,int>[2*N];
for(int i=1;i<2*N;i++){
tree[i]=e;
lazy[i]=I;
}
for(int i=2*N-1;i>0;i--){
if(i>=N) range[i]=make_pair(i-N, i-N+1);
else range[i]=make_pair(range[getChildren(i).first].first, range[getChildren(i).second].second);
}
}
~segTree(){
delete[] tree;
delete[] lazy;
delete[] range;
}
void update(int64_t value, int left, int right){
assert(0<=left && left<right && right<=N);
operate(value, 1, left, right, UPDATE);
}
void add(int64_t value, int left, int right){
assert(0<=left && left<right && right<=N);
operate(value, 1, left, right, ADD);
}
void update(int64_t value, int pos){
update(value, pos, pos+1);
}
void add(int64_t value, int pos){
add(value, pos, pos+1);
}
int64_t queue(int left, int right){
return get(1, left, right);
}
int64_t queue(int pos){
return get(1, pos, pos+1);
}
};
int main(){
cin.tie(nullptr);
ios::sync_with_stdio(false);
cout.precision(12);
cout.setf(ios_base::fixed, ios_base::floatfield);
int n, m, k;
cin >> n >> m >> k;
vector<pair<int, int>> lr;
for(int i=0;i<m;i++){
int l, r;
cin >> l >> r;
lr.push_back({l-1, r});
}
segTree st[2] = {n, n};
st[0].update(1, 0);
for(int s=1;s<=k;s++){
st[s%2].update(0, 0, n);
for(auto e:lr){
st[s%2].add(st[(s+1)%2].queue(e.first, e.second), e.first, e.second);
}
}
cout << st[n%2].queue(n-1) << endl;
return 0;
}