結果
| 問題 |
No.749 クエリ全部盛り
|
| コンテスト | |
| ユーザー |
chocorusk
|
| 提出日時 | 2019-09-06 16:06:17 |
| 言語 | C++11(廃止可能性あり) (gcc 13.3.0) |
| 結果 |
AC
|
| 実行時間 | 717 ms / 3,000 ms |
| コード長 | 4,385 bytes |
| コンパイル時間 | 1,443 ms |
| コンパイル使用メモリ | 118,468 KB |
| 実行使用メモリ | 44,016 KB |
| 最終ジャッジ日時 | 2024-06-23 23:45:30 |
| 合計ジャッジ時間 | 6,303 ms |
|
ジャッジサーバーID (参考情報) |
judge1 / judge5 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| other | AC * 20 |
コンパイルメッセージ
main.cpp: In function ‘int main()’:
main.cpp:143:14: warning: ignoring return value of ‘int scanf(const char*, ...)’ declared with attribute ‘warn_unused_result’ [-Wunused-result]
143 | scanf("%d %d", &n, &q);
| ~~~~~^~~~~~~~~~~~~~~~~
main.cpp:161:22: warning: ignoring return value of ‘int scanf(const char*, ...)’ declared with attribute ‘warn_unused_result’ [-Wunused-result]
161 | scanf("%d %d %d %d", &p, &l, &r, &k);
| ~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
ソースコード
#include <cstdio>
#include <cstring>
#include <iostream>
#include <string>
#include <cmath>
#include <bitset>
#include <vector>
#include <map>
#include <set>
#include <queue>
#include <deque>
#include <algorithm>
#include <complex>
#include <unordered_map>
#include <unordered_set>
#include <random>
#include <cassert>
#include <fstream>
#include <utility>
#include <functional>
#define popcount __builtin_popcount
using namespace std;
typedef long long int ll;
template<int MOD>
struct ModInt{
int x;
ModInt(): x(0){}
ModInt(ll y): x(y>=0 ? y%MOD : (MOD-(-y)%MOD)%MOD){}
ModInt &operator+=(const ModInt &p){
if((x+=p.x)>=MOD) x-=MOD;
return *this;
}
ModInt &operator-=(const ModInt &p){
if((x+=MOD-p.x)>=MOD) x-=MOD;
return *this;
}
ModInt &operator*=(const ModInt &p){
x=(int)(1ll*x*p.x%MOD);
return *this;
}
ModInt &operator/=(const ModInt &p){
*this*=p.inv();
return *this;
}
ModInt operator-() const{ return ModInt(-x);}
ModInt operator+(const ModInt &p) const{ return ModInt(*this)+=p;}
ModInt operator-(const ModInt &p) const{ return ModInt(*this)-=p;}
ModInt operator*(const ModInt &p) const{ return ModInt(*this)*=p;}
ModInt operator/(const ModInt &p) const{ return ModInt(*this)/=p;}
bool operator==(const ModInt &p) const{ return x==p.x;}
bool operator!=(const ModInt &p) const{ return x!=p.x;}
ModInt pow(ll n) const{
ModInt ret(1), p(x);
while(n){
if(n&1) ret*=p;
p*=p;
n>>=1;
}
return ret;
}
ModInt inv() const{
return pow(MOD-2);
}
};
const int MOD=1e9+7;
using modint=ModInt<MOD>;
typedef pair<modint, modint> P;
typedef pair<P, modint> Pm;
modint fib[1000010], fibs[1000010];
template<typename Monoid, typename OperatorMonoid=Monoid>
struct LazySegmentTree{
using F=function<Monoid(Monoid, Monoid)>;
using G=function<Monoid(Monoid, OperatorMonoid, int, int)>;
using H=function<OperatorMonoid(OperatorMonoid, OperatorMonoid)>;
int sz;
vector<Monoid> data;
vector<OperatorMonoid> lazy;
const F f;
const G g;
const H h;
const Monoid e1;
const OperatorMonoid e0;
LazySegmentTree(int n, const F f, const G g, const H h, const Monoid &e1, const OperatorMonoid &e0): f(f), g(g), h(h), e1(e1), e0(e0){
sz=1;
while(sz<n) sz<<=1;
data.resize(2*sz-1, e1);
lazy.resize(2*sz-1, e0);
}
void build(vector<Monoid> v){
for(int i=0; i<v.size(); i++) data[i+sz-1]=v[i];
for(int i=sz-2; i>=0; i--) data[i]=f(data[2*i+1], data[2*i+2]);
}
void eval(int k, int l, int r){
if(lazy[k]!=e0){
data[k]=g(data[k], lazy[k], l, r);
if(k<sz-1){
lazy[2*k+1]=h(lazy[2*k+1], lazy[k]);
lazy[2*k+2]=h(lazy[2*k+2], lazy[k]);
}
}
lazy[k]=e0;
}
void update(int a, int b, const OperatorMonoid &x, int k, int l, int r){
eval(k, l, r);
if(r<=a || b<=l) return;
if(a<=l && r<=b){
lazy[k]=h(lazy[k], x);
eval(k, l, r);
}else{
update(a, b, x, 2*k+1, l, (l+r)/2);
update(a, b, x, 2*k+2, (l+r)/2, r);
data[k]=f(data[2*k+1], data[2*k+2]);
}
}
void update(int a, int b, const OperatorMonoid &x){
return update(a, b, x, 0, 0, sz);
}
Monoid find(int a, int b, int k, int l, int r){
eval(k, l, r);
if(b<=l || r<=a) return e1;
if(a<=l && r<=b) return data[k];
else return f(find(a, b, 2*k+1, l, (l+r)/2), find(a, b, 2*k+2, (l+r)/2, r));
}
Monoid find(int a, int b){
return find(a, b, 0, 0, sz);
}
Monoid operator[](const int &k){
return find(k, k+1);
}
};
int main()
{
int n, q;
scanf("%d %d", &n, &q);
fib[0]=0, fib[1]=1;
for(int i=2; i<n; i++) fib[i]=fib[i-1]+fib[i-2];
fibs[0]=fibs[1]=0;
for(int i=1; i<n; i++) fibs[i+1]=fibs[i]+fib[i];
auto f=[](modint a, modint b){ return a+b;};
auto g=[&](modint a, Pm p, int l, int r){
modint x=p.first.first, y=p.first.second, z=p.second;
return x*a+y*(r-l)+z*(fibs[r]-fibs[l]);
};
auto h=[](Pm p1, Pm p2){
modint x1=p1.first.first, y1=p1.first.second, z1=p1.second;
modint x2=p2.first.first, y2=p2.first.second, z2=p2.second;
return Pm(P(x1*x2, x2*y1+y2), x2*z1+z2);
};
LazySegmentTree<modint, Pm> seg(n, f, g, h, 0, Pm(P(1, 0), 0));
for(int z=0; z<q; z++){
int p, l, r, k;
scanf("%d %d %d %d", &p, &l, &r, &k);
if(p==0) printf("%d\n", (modint(k)*seg.find(l, r+1)).x);
else if(p==1) seg.update(l, r+1, Pm(P(0, k), 0));
else if(p==2) seg.update(l, r+1, Pm(P(1, k), 0));
else if(p==3) seg.update(l, r+1, Pm(P(k, 0), 0));
else seg.update(l, r+1, Pm(P(1, 0), k));
}
return 0;
}
chocorusk