結果
| 問題 |
No.801 エレベーター
|
| コンテスト | |
| ユーザー |
|
| 提出日時 | 2019-03-17 23:31:11 |
| 言語 | C++17 (gcc 13.3.0 + boost 1.87.0) |
| 結果 |
TLE
|
| 実行時間 | - |
| コード長 | 3,946 bytes |
| コンパイル時間 | 3,447 ms |
| コンパイル使用メモリ | 213,952 KB |
| 最終ジャッジ日時 | 2025-01-06 23:16:38 |
|
ジャッジサーバーID (参考情報) |
judge1 / judge3 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| sample | AC * 3 |
| other | AC * 11 TLE * 15 |
ソースコード
#include <bits/stdc++.h>
using namespace std;
const uint64_t M = 1'000'000'007;
enum rangeOperaion{
NUL,
UPDATE,
ADD
};
using ll = int64_t;
class segTree{
int N;
ll *tree;
pair<rangeOperaion, ll> *lazy;
const pair<rangeOperaion, ll> nullopr=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(ll N){
int lgN;
for(lgN=0;(1<<lgN)<N;lgN++);
return lgN;
}
void setLazy(int pos, pair<rangeOperaion, ll> 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){
tree[pos]=lazy[pos].second*(range[pos].second-range[pos].first);
tree[pos] %= M;
}else{
tree[pos]+=lazy[pos].second*(range[pos].second-range[pos].first);
tree[pos] %= M;
}
lazy[pos]=nullopr;
}
void operate(ll 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]=tree[getChildren(pos).first] + tree[getChildren(pos).second];
tree[pos] %= M;
}
ll get(int pos, int left, int right){
eval(pos);
if(right<=range[pos].first || range[pos].second<=left) return 0;
if(left<=range[pos].first && range[pos].second<=right) return tree[pos];
return (get(getChildren(pos).first, left, right) + get(getChildren(pos).second, left, right))%M;
}
public:
segTree(int n){
N=(1LL<<lg(n));
if(N<n) N*=2;
tree=new ll[2*N];
lazy=new pair<rangeOperaion,ll>[2*N];
range=new pair<int,int>[2*N];
for(int i=1;i<2*N;i++){
tree[i]=0;
lazy[i]=nullopr;
}
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(ll value, int left, int right){
assert(0<=left && left<right && right<=N);
operate(value, 1, left, right, UPDATE);
}
void add(ll value, int left, int right){
assert(0<=left && left<right && right<=N);
operate(value, 1, left, right, ADD);
}
void update(ll value, int pos){
update(value, pos, pos+1);
}
void add(ll value, int pos){
add(value, pos, pos+1);
}
ll queue(int left, int right){
return get(1, left, right);
}
ll 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;
int l[3000], r[3000];
for(int i=0;i<m;i++){
cin >> l[i] >> r[i];
l[i]--;
r[i]--;
}
segTree st[2] = {3000, 3000};
st[0].update(1, 0);
for(int i=1;i<=k;i++){
st[i%2].update(0, 0, n);
for(int j=0;j<m;j++) st[i%2].add(st[(i+1)%2].queue(l[j], r[j]+1), l[j], r[j]+1);
}
cout << st[k%2].queue(n-1) << endl;
return 0;
}