結果
| 問題 |
No.749 クエリ全部盛り
|
| コンテスト | |
| ユーザー |
ats5515
|
| 提出日時 | 2018-10-19 23:05:24 |
| 言語 | C++11(廃止可能性あり) (gcc 13.3.0) |
| 結果 |
AC
|
| 実行時間 | 1,423 ms / 3,000 ms |
| コード長 | 3,930 bytes |
| コンパイル時間 | 812 ms |
| コンパイル使用メモリ | 88,672 KB |
| 実行使用メモリ | 93,028 KB |
| 最終ジャッジ日時 | 2024-11-18 22:19:39 |
| 合計ジャッジ時間 | 9,402 ms |
|
ジャッジサーバーID (参考情報) |
judge4 / judge2 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| other | AC * 20 |
ソースコード
#include <iostream>
#include <vector>
#include <map>
#include <set>
#include <queue>
#include <string>
#include <iomanip>
#include <algorithm>
#include <cmath>
#include <stdio.h>
using namespace std;
int MOD = 1000000007;
using uint = unsigned int;
#define int long long
int fs[1050100];
int fib(int l, int r) {
int res = (fs[r] - fs[l]) % MOD;
if (res < 0)res += MOD;
return res;
}
template<class T> using V = vector<T>;
template<class OP>
struct SegTree {
using D = typename OP::D;
using L = typename OP::L;
static constexpr auto e_d = OP::e_d;
static constexpr auto e_l = OP::e_l;
static constexpr auto op_dd = OP::op_dd;
static constexpr auto op_dl = OP::op_dl;
static constexpr auto op_ll = OP::op_ll;
int sz, lg; //(2^lgに拡張後の)サイズ, lg
V<D> d;
V<L> lz;
SegTree(int n) : SegTree(V<D>(n, e_d())) {}
SegTree(V<D> first) {
int n = (int)(first.size());
lg = 1;
while ((1 << lg) < n) lg++;
sz = 1 << lg;
d = V<D>(2 * sz, e_d());
lz = V<L>(2 * sz, e_l());
for (int i = 0; i < n; i++) d[sz + i] = first[i];
for (int i = sz - 1; i >= 0; i--) {
update(i);
}
}
void all_add(int k, L x, int l, int r) {
d[k] = op_dl(d[k], x, l, r);
lz[k] = op_ll(lz[k], x);
}
void push(int k, int l, int r) {
int mid = (l + r) / 2;
all_add(2 * k, lz[k], l, mid);
all_add(2 * k + 1, lz[k], mid, r);
lz[k] = e_l();
}
void update(int k) {
d[k] = op_dd(d[2 * k], d[2 * k + 1]);
}
D sum(int a, int b, int l, int r, int k) {
if (b <= l || r <= a) return e_d();
if (a <= l && r <= b) return d[k];
push(k, l, r);
int mid = (l + r) / 2;
return op_dd(sum(a, b, l, mid, 2 * k), sum(a, b, mid, r, 2 * k + 1));
}
D sum(int a, int b) { return sum(a, b, 0, sz, 1); }
void add(int a, int b, L x, int l, int r, int k) {
//cerr << l << " " << r << endl;
if (b <= l || r <= a) return;
if (a <= l && r <= b) {
all_add(k, x, l, r);
return;
}
push(k, l, r);
int mid = (l + r) / 2;
add(a, b, x, l, mid, 2 * k); add(a, b, x, mid, r, 2 * k + 1);
update(k);
}
void add(int a, int b, L x) { add(a, b, x, 0, sz, 1); }
};
//starry sky tree
struct LZ {
int add = 0;
int mul = 1;
int update = -1;
int fa = 0;
};
struct OP {
using D = int;
using L = LZ;
static constexpr D e_d() { return 0; }
static constexpr L e_l() { return L(); }
static D op_dd(D l, D r) {
return (l + r) % MOD;
}
static D op_dl(D l, const L &r, int le, int ri) {
D d;
int len = (ri - le);
if (r.update == -1) {
d = l;
}
else {
d = (r.update*len) % MOD;
}
//cerr << le << " " << ri << endl;
//cerr << r.update << " " << r.mul << " " << r.add << " " << r.fa << " " << d <<endl;
d = (d*r.mul) % MOD;
d = (d + ((r.add * len) % MOD)) % MOD;
d = (d + ((r.fa*fib(le, ri)) % MOD)) % MOD;
return d;
}
static L op_ll(const L &l, const L &r) {
L n;
if (r.update != -1) {
n = r;
}
else {
n.update = l.update;
n.mul = (l.mul*r.mul) % MOD;
n.add = (((l.add * r.mul) % MOD) + r.add) % MOD;
n.fa = (((l.fa * r.mul) % MOD) + r.fa) % MOD;
}
return n;
}
};
signed main() {
cin.tie(0);
ios::sync_with_stdio(false);
int N, Q;
cin >> N >> Q;
auto seg = SegTree<OP>(N);
int q, l, r, k;
fs[0] = 0;
fs[1] = 0;
fs[2] = 1;
for (int i = 3; i <= N + 2; i++) {
fs[i] = (fs[i - 1] + fs[i - 2]) % MOD;
}
for (int i = 1; i <= N + 2; i++) {
fs[i] = (fs[i] + fs[i - 1]);
}
cerr << "OK" << endl;
for (int i = 0; i < Q; i++) {
cin >> q >> l >> r >> k;
LZ lazy;
if (q == 0) {
int t = seg.sum(l, r + 1);
t = (t * k) % MOD;
cout << t << endl;
}
else if (q == 1) {
lazy.update = k;
seg.add(l, r + 1, lazy);
}
else if (q == 2) {
lazy.add = k;
seg.add(l, r + 1, lazy);
}
else if (q == 3) {
lazy.mul = k;
seg.add(l, r + 1, lazy);
}
else if (q == 4) {
lazy.fa = k;
seg.add(l, r + 1, lazy);
}
}
/*for (int i = 0; i < N; i++) {
cerr << seg.sum(i, i + 1) << " ";
}
cerr << endl;
*/
}
ats5515