結果
| 問題 |
No.749 クエリ全部盛り
|
| コンテスト | |
| ユーザー |
pred
|
| 提出日時 | 2021-01-06 19:26:25 |
| 言語 | C++17 (gcc 13.3.0 + boost 1.87.0) |
| 結果 |
CE
(最新)
AC
(最初)
|
| 実行時間 | - |
| コード長 | 7,596 bytes |
| コンパイル時間 | 536 ms |
| コンパイル使用メモリ | 76,032 KB |
| 最終ジャッジ日時 | 2025-01-17 09:56:32 |
|
ジャッジサーバーID (参考情報) |
judge5 / judge5 |
(要ログイン)
コンパイルエラー時のメッセージ・ソースコードは、提出者また管理者しか表示できないようにしております。(リジャッジ後のコンパイルエラーは公開されます)
ただし、clay言語の場合は開発者のデバッグのため、公開されます。
ただし、clay言語の場合は開発者のデバッグのため、公開されます。
コンパイルメッセージ
main.cpp: In function ‘int main()’:
main.cpp:212:21: error: no matching function for call to ‘segment_tree<RsummodQ_RaffineQ<long long int, 1000000007> >::apply(long long int&, long long int, <brace-enclosed initializer list>)’
212 | st.apply(x, y + 1, {0, z, 0});
| ~~~~~~~~^~~~~~~~~~~~~~~~~~~~~
main.cpp:63:10: note: candidate: ‘void segment_tree<U>::apply(int, int, E) [with U = RsummodQ_RaffineQ<long long int, 1000000007>; E = std::array<long long int, 3>]’
63 | void apply(int bg, int ed, E query){
| ^~~~~
main.cpp:63:34: note: no known conversion for argument 3 from ‘<brace-enclosed initializer list>’ to ‘segment_tree<RsummodQ_RaffineQ<long long int, 1000000007> >::E’ {aka ‘std::array<long long int, 3>’}
63 | void apply(int bg, int ed, E query){
| ~~^~~~~
main.cpp:104:10: note: candidate: ‘void segment_tree<U>::apply(int, E) [with U = RsummodQ_RaffineQ<long long int, 1000000007>; E = std::array<long long int, 3>]’
104 | void apply(int ind, E query){
| ^~~~~
main.cpp:104:10: note: candidate expects 2 arguments, 3 provided
main.cpp:215:21: error: no matching function for call to ‘segment_tree<RsummodQ_RaffineQ<long long int, 1000000007> >::apply(long long int&, long long int, <brace-enclosed initializer list>)’
215 | st.apply(x, y + 1, {1, z, 0});
| ~~~~~~~~^~~~~~~~~~~~~~~~~~~~~
main.cpp:63:10: note: candidate: ‘void segment_tree<U>::apply(int, int, E) [with U = RsummodQ_RaffineQ<long long int, 1000000007>; E = std::array<long long int, 3>]’
63 | void apply(int bg, int ed, E query){
| ^~~~~
main.cpp:63:34: note: no known conversion for argument 3 from ‘<brace-enclosed initializer list>’ to ‘segment_tree<RsummodQ_RaffineQ<long long int, 1000000007> >::E’ {aka ‘std::array<long long int, 3>’}
63 | void apply(int bg, int ed, E query){
ソースコード
#include <iostream>
#include <vector>
#include <algorithm>
#include <iomanip>
template <typename U>
class segment_tree{
using T = typename U::typeT;
using E = typename U::typeE;
int num = 0, lognum = 0;
std::vector<T> segtree_t;
std::vector<E> segtree_e;
std::vector<int> width;
public:
segment_tree(int n, T deft = U::e_t){
_constructor(n);
std::fill(segtree_t.begin() + (1 << lognum), segtree_t.begin() + (1 << lognum) + n, deft);
if(U::segtree_type != 2) for(int i = (1 << lognum) - 1; i != 0; i--){
segtree_t[i] = U::func_tt(segtree_t[i << 1], segtree_t[(i << 1) + 1]);
}
}
segment_tree(std::vector<T> &vec){
_constructor(vec.size());
std::copy(vec.begin(), vec.end(), segtree_t.begin() + (1 << lognum));
if(U::segtree_type != 2) for(int i = (1 << lognum) - 1; i != 0; i--){
segtree_t[i] = U::func_tt(segtree_t[i << 1], segtree_t[(i << 1) + 1]);
}
}
void _constructor(int n){
num = n;
while((1 << lognum) < n) lognum++;
segtree_t = std::vector<T>(1 << (lognum + 1), U::e_t);
if(U::segtree_type != 1){
segtree_e = std::vector<E>(1 << (lognum + 1), U::e_e);
}
if(U::segtree_type == 3){
width = std::vector<int>(1 << (lognum + 1), 1);
for(int i = (1 << lognum) - 1; i != 0; i--){
width[i] = width[i << 1] + width[(i << 1) + 1];
}
}
}
inline void split_query(int ind){
int ind2 = (ind << 1);
if(U::segtree_type == 3){
segtree_t[ind2] = U::func_te(segtree_t[ind2] , segtree_e[ind], width[ind2]);
segtree_t[ind2 + 1] = U::func_te(segtree_t[ind2 + 1], segtree_e[ind], width[ind2]);
}
if(U::segtree_type != 1){
segtree_e[ind2] = U::func_ee(segtree_e[ind2] , segtree_e[ind]);
segtree_e[ind2 + 1] = U::func_ee(segtree_e[ind2 + 1], segtree_e[ind]);
segtree_e[ind] = U::e_e;
}
}
void apply(int bg, int ed, E query){
if(U::segtree_type != 1){
bg += (1 << lognum);
ed += (1 << lognum);
for(int i = lognum; i >= 1; i--){
if(((bg >> i) << i) != bg) split_query(bg >> i);
if(((ed >> i) << i) != ed) split_query((ed - 1) >> i);
}
int bg_temp = bg, ed_temp = ed - 1;
while(bg_temp < ed_temp){
if(bg_temp & 1){
segtree_e[bg_temp] = U::func_ee(segtree_e[bg_temp], query);
if(U::segtree_type == 3) segtree_t[bg_temp] = U::func_te(segtree_t[bg_temp], query, width[bg_temp]);
bg_temp++;
}
if(~ed_temp & 1){
segtree_e[ed_temp] = U::func_ee(segtree_e[ed_temp], query);
if(U::segtree_type == 3) segtree_t[ed_temp] = U::func_te(segtree_t[ed_temp], query, width[ed_temp]);
ed_temp--;
}
bg_temp >>= 1;
ed_temp >>= 1;
}
if(bg_temp == ed_temp){
segtree_e[bg_temp] = U::func_ee(segtree_e[bg_temp], query);
if(U::segtree_type == 3) segtree_t[bg_temp] = U::func_te(segtree_t[bg_temp], query, width[bg_temp]);
}
if(U::segtree_type == 3) for(int i = 1; i <= lognum; i++){
if(((bg >> i) << i) != bg){
segtree_t[bg >> i] = U::func_tt(segtree_t[(bg >> i) << 1], segtree_t[((bg >> i) << 1) + 1]);
}
if(((ed >> i) << i) != ed){
segtree_t[(ed - 1) >> i] = U::func_tt(segtree_t[((ed - 1) >> i) << 1], segtree_t[(((ed - 1) >> i) << 1) + 1]);
}
}
}
}
void apply(int ind, E query){
if(U::segtree_type == 1){
ind += (1 << lognum);
segtree_t[ind] = U::func_te(segtree_t[ind], query, 1);
ind >>= 1;
for(; ind != 0; ind >>= 1){
segtree_t[ind] = U::func_tt(segtree_t[ind << 1], segtree_t[(ind << 1) + 1]);
}
}
}
T find(int bg, int ed){
if(U::segtree_type != 2){
bg += (1 << lognum);
ed += (1 << lognum);
if(U::segtree_type == 3) for(int i = lognum; i >= 1; i--){
if(((bg >> i) << i) != bg) split_query(bg >> i);
if(((ed >> i) << i) != ed) split_query((ed - 1) >> i);
}
T res1 = U::e_t, res2 = U::e_t;
ed--;
while(bg < ed){
if(bg & 1){
res1 = U::func_tt(res1, segtree_t[bg]);
bg++;
}
if(~ed & 1){
res2 = U::func_tt(segtree_t[ed], res2);
ed--;
}
bg >>= 1;
ed >>= 1;
}
if(bg == ed) res1 = U::func_tt(res1, segtree_t[bg]);
res1 = U::func_tt(res1, res2);
return res1;
}
return U::e_t;
}
T find(int ind){
if(U::segtree_type == 2){
ind += (1 << lognum);
for(int i = lognum; i >= 1; i--){
split_query(ind >> i);
}
segtree_t[ind] = U::func_te(segtree_t[ind], segtree_e[ind], 1);
segtree_e[ind] = U::e_e;
return segtree_t[ind];
}
return U::e_t;
}
void print(int n){
std::cout << "val : ";
for(auto itr = segtree_t.begin(); itr != segtree_t.end(); itr++){
std::cout << std::right << std::setw(n) << *itr << " ";
}
std::cout << "\n";
std::cout << "lazy: ";
for(auto itr = segtree_e.begin(); itr != segtree_e.end(); itr++){
std::cout << std::right << std::setw(n) << *itr << " ";
}
std::cout << "\n";
}
};
template <typename T, long long MOD>
struct RsummodQ_RaffineQ{
static constexpr int segtree_type = 3;
using typeT = std::pair<T, T>;
using typeE = std::array<T, 3>;
static constexpr typeT e_t = std::make_pair(0, 0);
static constexpr typeE e_e = {1, 0, 0};
static typeT func_tt(typeT a, typeT b){
return std::make_pair((a.first + b.first) % MOD, (a.second + b.second) % MOD);
}
static typeT func_te(typeT a, typeE b, int w){
return std::make_pair((a.first * b[0] + b[1] * (long long)w + a.second * b[2]) % MOD, a.second);
}
static typeE func_ee(typeE a, typeE b){
return {(a[0] * b[0]) % MOD, (a[1] * b[0] + b[1]) % MOD, (a[2] * b[0] + b[2]) % MOD};
}
};
int main(){
std::ios::sync_with_stdio(false);
std::cin.tie(0);
const long long mod = 1e9 + 7;
long long n, q, op, x, y, z;
std::cin >> n >> q;
std::vector<std::pair<long long, long long>> vec(n, {0, 1});
vec[0].second = 0;
for(int i = 2; i < n; i++) vec[i].second = (vec[i-1].second + vec[i-2].second) % mod;
segment_tree<RsummodQ_RaffineQ<long long, mod>> st(vec);
while(q--){
std::cin >> op >> x >> y >> z;
if(op == 0){
std::cout << (st.find(x, y + 1).first * z) % mod << "\n";
}
else if(op == 1){
st.apply(x, y + 1, {0, z, 0});
}
else if(op == 2){
st.apply(x, y + 1, {1, z, 0});
}
else if(op == 3){
st.apply(x, y + 1, {z, 0, 0});
}
else if(op == 4){
st.apply(x, y + 1, {1, 0, z});
}
}
}
pred