結果
| 問題 |
No.1675 Strange Minimum Query
|
| コンテスト | |
| ユーザー |
|
| 提出日時 | 2021-09-10 22:31:58 |
| 言語 | C++17 (gcc 13.3.0 + boost 1.87.0) |
| 結果 |
WA
|
| 実行時間 | - |
| コード長 | 6,618 bytes |
| コンパイル時間 | 2,821 ms |
| コンパイル使用メモリ | 204,092 KB |
| 最終ジャッジ日時 | 2025-01-24 11:34:17 |
|
ジャッジサーバーID (参考情報) |
judge5 / judge4 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| sample | AC * 3 |
| other | AC * 22 WA * 12 |
ソースコード
#include <bits/stdc++.h>
using namespace std;
typedef pair<int, int> P;
template<typename S, S (*XX)(S, S), S (*id)(), typename F, F (*FF)(F, F), S (*FX)(F, S), F (*e)()> struct lazy_segment_tree{
private:
int n;
int size;//元の配列の大きさ
int height; //セグ木の高さの最大値 - 1
vector<S> dat;
vector<F> lazy;
void update_sub(int k){
dat[k] = XX(dat[k << 1 | 0], dat[k << 1 | 1]);
}
//伝搬用の関数
void push(int k){
operate(2 * k, lazy[k]);
operate(2 * k + 1, lazy[k]);
lazy[k] = e();
}
//伝搬してきた遅延を作用させ、遅延部分を増幅(というより結合)させる
void operate(int k, F x){
dat[k] = FX(x, dat[k]);
if(k < size) lazy[k] = FF(x, lazy[k]);
}
public:
lazy_segment_tree(int n_) : n(n_ * 2), size(n_){
dat.resize(n, id());
lazy.resize(n, e());
height = 0;
int t = 1;
while(t < n_){
height++;
t *= 2;
}
}
lazy_segment_tree(vector<S> &v){
size = (int)v.size();
n = size * 2;
dat.resize(n, id());
height = 0;
int t = 1;
while(t < size){
t *= 2;
height++;
}
lazy.resize(n, e());
for(int i = 0; i < size; i++) dat[i + size] = v[i];
for(int i = size - 1; i >= 1; i--){
update_sub(i);
}
}
//区間更新
void update(int l, int r, F a){
int l1 = l + size;
int r1 = r + size;
for(int i = height; i >= 1; i--){
if(((l1 >> i) << i) != l1 && (l1 >> i) >= 1) push(l1 >> i);
if(((r1 >> i) << i) != r1 && (r1 >> i) >= 1) push(r1 >> i);
}
while(r1 > l1){
if(l1 & 1) operate(l1++, a);
if(r1 & 1) operate(--r1, a);
r1 >>= 1;
l1 >>= 1;
}
l1 = l + size;
r1 = r + size;
for(int i = 1; i <= height; i++){
if(((l1 >> i) << i) != l1 && (l1 >> i) >= 1) update_sub(l1 >> i);
if(((r1 >> i) << i) != r1 && (r1 >> i) >= 1) update_sub(r1 >> i);
}
}
//一点更新
void update(int ind, F a){
ind += size;
for(int i = height; i >= 1; i--){
if((ind >> i) >= 1) push(ind >> i);
}
dat[ind] = FX(a, dat[ind]);
for(int i = 1; i <= height; i++){
if((ind >> i) >= 1) update_sub(ind >> i);
}
}
//区間mergeを取得
S query(int l, int r){
if(l >= r) return id();
S resr = id(), resl = id();
l += size;
r += size;
for(int i = height; i >= 1; i--){
if(((l >> i) << i) != l && (l >> i) >= 1) push(l >> i);
if(((r >> i) << i) != r && (r >> i) >= 1) push(r >> i);
}
while(r > l){
if(l & 1) resl = XX(resl, dat[l++]);
if(r & 1) resr = XX(dat[--r], resr);
l >>= 1;
r >>= 1;
}
return XX(resl, resr);
}
S all_query(){
return dat[1];
}
//[l, r)でf(merge(a[l],..., a[r - 1]))がtrueとなる最大のrを返す
template<typename op>
int max_right(int l, op f){
if(l == size) return size;
stack<int> s;
queue<int> q;
l += size;
int r = n;
for(int i = height; i >= 1; i--){
if(((l >> i) << i) != l && (l >> i) >= 1) push(l >> i);
}
while(r > l){
if(l & 1){
q.push(l++);
}
if(r & 1){
s.push(--r);
}
r >>= 1;
l >>= 1;
}
while(!s.empty()){
q.push(s.top());
s.pop();
}
S res = id();
int now = -1;
while(!q.empty()){
int v = q.front();
q.pop();
S temp = XX(res, dat[v]);
if(!f(temp)){
now = v;
break;
}
res = temp;
}
if(now == -1) return size;
while(now < size){
push(now);
now <<= 1;
S temp = XX(res, dat[now]);
if(f(temp)){
res = temp;
now++;
}
}
return now - size;
}
//[l, r)でf(merge(a[l],..., a[r - 1]))がtrueとなる最小のlを返す
template<typename op>
int min_left(int r, op f){
if(r == 0) return 0;
stack<int> s;
queue<int> q;
int l = size;
r += size;
for(int i = height; i >= 1; i--){
if(((r >> i) << i) != r && (r >> i) >= 1) push(r >> i);
}
while(r > l){
if(r & 1) q.push(--r);
if(l & 1) s.push(l++);
r >>= 1;
l >>= 1;
}
while(!s.empty()){
q.push(s.top());
s.pop();
}
S res = id();
int now = -1;
while(!q.empty()){
int v = q.front();
q.pop();
S temp = XX(res, dat[v]);
if(!f(temp)){
now = v;
break;
}
res = temp;
}
if(now == -1) return 0;
while(now < size){
push(now);
now <<= 1;
now++;
S temp = XX(res, dat[now]);
if(f(temp)){
res = temp;
now--;
}
}
return now + 1 - size;
}
};
int INF = 1000000000;
int XX(int x, int y){
return min(x, y);
}
int id(){
return INF;
}
int FF(int x, int y){
if(x == INF) return y;
else if(y != INF) return y;
return x;
}
int FX(int x, int y){
if(y == INF) return x;
return y;
}
int e(){
return INF;
}
int main(){
int N, Q;
cin >> N >> Q;
vector<int> A(N, INF);
lazy_segment_tree<int, XX, id, int, FF, FX, e> seg(A);
vector<int> L(Q), R(Q), B(Q);
for(int i = 0; i < Q; i++) {
cin >> L[i] >> R[i] >> B[i];
L[i]--;
}
vector<int> ind(Q);
iota(ind.begin(), ind.end(), 0);
sort(ind.begin(), ind.end(), [&](int x, int y){
return B[x] > B[y];
});
for(int i = 0; i < Q; i++){
seg.update(L[ind[i]], R[ind[i]], B[ind[i]]);
}
for(int i = 0; i < Q; i++){
int temp = seg.query(L[i], R[i]);
if(temp != B[i]){
cout << -1 << endl;
return 0;
}
}
for(int i = 0; i < N; i++){
if(i != N - 1) cout << seg.query(i, i + 1) << ' ';
else cout << seg.query(i, i + 1) << endl;
}
}