結果
| 問題 |
No.749 クエリ全部盛り
|
| コンテスト | |
| ユーザー |
tnakao0123
|
| 提出日時 | 2018-10-25 19:29:05 |
| 言語 | C++11(廃止可能性あり) (gcc 13.3.0) |
| 結果 |
AC
|
| 実行時間 | 1,587 ms / 3,000 ms |
| コード長 | 4,640 bytes |
| コンパイル時間 | 1,374 ms |
| コンパイル使用メモリ | 103,132 KB |
| 実行使用メモリ | 101,760 KB |
| 最終ジャッジ日時 | 2024-11-19 05:45:13 |
| 合計ジャッジ時間 | 10,469 ms |
|
ジャッジサーバーID (参考情報) |
judge2 / judge3 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| other | AC * 20 |
コンパイルメッセージ
main.cpp: In function ‘int main()’:
main.cpp:174:8: warning: ignoring return value of ‘int scanf(const char*, ...)’ declared with attribute ‘warn_unused_result’ [-Wunused-result]
174 | scanf("%d%d", &n, &qn);
| ~~~~~^~~~~~~~~~~~~~~~~
main.cpp:180:10: warning: ignoring return value of ‘int scanf(const char*, ...)’ declared with attribute ‘warn_unused_result’ [-Wunused-result]
180 | scanf("%d%d%d%d", &q, &l, &r, &k);
| ~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~
ソースコード
/* -*- coding: utf-8 -*-
*
* 749.cc: No.749 クエリ全部盛り - yukicoder
*/
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<iostream>
#include<string>
#include<vector>
#include<map>
#include<set>
#include<stack>
#include<list>
#include<queue>
#include<deque>
#include<algorithm>
#include<numeric>
#include<utility>
#include<complex>
#include<functional>
using namespace std;
/* constant */
const int MAX_N = 1000000;
const int MAX_E2 = 1 << 21; // = 2097152
const int D = 3;
const int MOD = 1000000007;
/* typedef */
typedef long long ll;
typedef int vec[D];
typedef vec mat[D];
inline void initmat(mat a);
inline void unitmat(mat a);
inline void copymat(const mat a, mat b);
inline void mulmat(const mat a, const mat b, mat c);
inline void mulmatvec(const mat a, const vec b, vec c);
template <typename T, const int MAX_E2>
struct SegTreeFibo {
int n, e2, ls[MAX_E2];
T as[MAX_E2], fs[MAX_E2];
bool dfs[MAX_E2];
mat ms[MAX_E2];
SegTreeFibo() {}
void init(int _n) {
n = _n;
for (e2 = 1; e2 < n; e2 <<= 1);
fs[e2 - 1 + 0] = 0, fs[e2 - 1 + 1] = 1;
for (int i = 2, j = e2 - 1 + i; i < n; i++, j++)
fs[j] = (fs[j - 1] + fs[j - 2]) % MOD;
for (int i = 0; i < e2; i++) ls[e2 - 1 + i] = 1;
for (int i = e2 - 2; i >= 0; i--) {
int i1 = i * 2 + 1, i2 = i1 + 1;
fs[i] = (fs[i1] + fs[i2]) % MOD;
ls[i] = ls[i1] + ls[i2];
}
for (int i = e2 - 2 + n; i >= 0; i--) unitmat(ms[i]);
}
T get(int i) { return as[e2 - 1 + i]; }
void op_delegate(int k, int k1) {
mat m1;
vec v0, v1;
v0[0] = as[k1], v0[1] = fs[k1], v0[2] = ls[k1];
mulmatvec(ms[k], v0, v1);
as[k1] = v1[0];
mulmat(ms[k], ms[k1], m1);
copymat(m1, ms[k1]);
dfs[k1] = true;
}
void op_range(int r0, int r1, mat m, int k, int i0, int i1) {
if (r1 <= i0 || i1 <= r0) return;
mat m1;
vec v0, v1;
if (r0 <= i0 && i1 <= r1) {
v0[0] = as[k], v0[1] = fs[k], v0[2] = ls[k];
mulmatvec(m, v0, v1);
as[k] = v1[0];
mulmat(m, ms[k], m1);
copymat(m1, ms[k]);
dfs[k] = true;
return;
}
int k1 = k * 2 + 1, k2 = k1 + 1;
if (dfs[k]) {
op_delegate(k, k1);
op_delegate(k, k2);
unitmat(ms[k]);
dfs[k] = false;
}
int im = (i0 + i1) / 2;
op_range(r0, r1, m, k1, i0, im);
op_range(r0, r1, m, k2, im, i1);
as[k] = (as[k1] + as[k2]) % MOD;
}
void op_range(int r0, int r1, mat m) { op_range(r0, r1, m, 0, 0, e2); }
T sum_range(int r0, int r1, int k, int i0, int i1) {
if (r1 <= i0 || i1 <= r0) return 0;
if (r0 <= i0 && i1 <= r1) return as[k];
int k1 = k * 2 + 1, k2 = k1 + 1;
if (dfs[k]) {
op_delegate(k, k1);
op_delegate(k, k2);
unitmat(ms[k]);
dfs[k] = false;
}
int im = (i0 + i1) / 2;
T v0 = sum_range(r0, r1, k1, i0, im);
T v1 = sum_range(r0, r1, k2, im, i1);
return (v0 + v1) % MOD;
}
T sum_range(int r0, int r1) {
return sum_range(r0, r1, 0, 0, e2);
}
};
/* global variables */
SegTreeFibo<int,MAX_E2> st;
/* subroutines */
inline void initmat(mat a) { memset(a, 0, sizeof(mat)); }
inline void unitmat(mat a) {
initmat(a);
for (int i = 0; i < D; i++) a[i][i] = 1;
}
inline void copymat(const mat a, mat b) { memcpy(b, a, sizeof(mat)); }
inline void mulmat(const mat a, const mat b, mat c) {
for (int i = 0; i < D; i++)
for (int j = 0; j < D; j++) {
c[i][j] = 0;
for (int k = 0; k < D; k++)
c[i][j] = (c[i][j] + (ll)a[i][k] * b[k][j] % MOD) % MOD;
}
}
inline void mulmatvec(const mat a, const vec b, vec c) {
for (int i = 0; i < D; i++) {
c[i] = 0;
for (int j = 0; j < D; j++)
c[i] = (c[i] + (ll)a[i][j] * b[j] % MOD) % MOD;
}
}
/* main */
int main() {
int n, qn;
scanf("%d%d", &n, &qn);
st.init(n);
while (qn--) {
int q, l, r, k;
scanf("%d%d%d%d", &q, &l, &r, &k);
r++;
if (q == 0) {
int sum = st.sum_range(l, r);
printf("%lld\n", (ll)sum * k % MOD);
}
else {
mat m;
unitmat(m);
switch (q) {
// 1: ai = k
case 1: m[0][0] = 0, m[0][2] = k; break;
// 2: ai = ai + k
case 2: m[0][2] = k; break;
// 3: ai = ai * k
case 3: m[0][0] = k; break;
// 4: ai = ai + k * fi
case 4: m[0][1] = k; break;
}
st.op_range(l, r, m);
/*
for (int i = 0; i < st.e2 - 1; i++) {
int i1 = 2 * i + 1, i2 = i1 + 1;
st.op_delegate(i, i1);
st.op_delegate(i, i2);
}
for (int i = 0; i < st.e2 * 2 - 1; i++) printf("%d ", st.as[i]);
putchar('\n');
*/
}
}
return 0;
}
tnakao0123