結果
| 問題 |
No.880 Yet Another Segment Tree Problem
|
| コンテスト | |
| ユーザー |
chocorusk
|
| 提出日時 | 2019-09-08 14:58:22 |
| 言語 | C++11(廃止可能性あり) (gcc 13.3.0) |
| 結果 |
AC
|
| 実行時間 | 731 ms / 5,000 ms |
| コード長 | 2,827 bytes |
| コンパイル時間 | 1,262 ms |
| コンパイル使用メモリ | 108,960 KB |
| 実行使用メモリ | 12,288 KB |
| 最終ジャッジ日時 | 2025-06-20 10:28:54 |
| 合計ジャッジ時間 | 15,278 ms |
|
ジャッジサーバーID (参考情報) |
judge5 / judge2 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| sample | AC * 1 |
| other | AC * 38 |
ソースコード
#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;
typedef pair<int, int> P;
const ll INF=2e18;
ll gcd(ll a, ll b){
if(b==0) return a;
return gcd(b, a%b);
}
ll lcm(ll a, ll b){
if(a==INF || b==INF) return INF;
ll g=gcd(a, b);
if(a/g>=(INF+b-1)/b) return INF;
else return a/g*b;
}
int n, sz;
vector<ll> mx, sum, vlcm, lazy;
ll a[1<<17];
void init(){
sz=1;
while(sz<n) sz<<=1;
mx.resize(2*sz-1);
sum.resize(2*sz-1);
vlcm.resize(2*sz-1, 1);
lazy.resize(2*sz-1);
for(int i=0; i<n; i++){
mx[i+sz-1]=sum[i+sz-1]=vlcm[i+sz-1]=a[i];
}
for(int i=sz-2; i>=0; i--){
mx[i]=max(mx[2*i+1], mx[2*i+2]);
sum[i]=sum[2*i+1]+sum[2*i+2];
vlcm[i]=lcm(vlcm[2*i+1], vlcm[2*i+2]);
}
}
void eval(int k, int l, int r){
if(lazy[k]!=0){
mx[k]=vlcm[k]=lazy[k];
sum[k]=(r-l)*lazy[k];
if(k<sz-1){
lazy[2*k+1]=lazy[k];
lazy[2*k+2]=lazy[k];
}
}
lazy[k]=0;
}
void update(int a, int b, ll x, int k, int l, int r){
eval(k, l, r);
if(r<=a || b<=l) return;
if(a<=l && r<=b){
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);
mx[k]=max(mx[2*k+1], mx[2*k+2]);
sum[k]=sum[2*k+1]+sum[2*k+2];
vlcm[k]=lcm(vlcm[2*k+1], vlcm[2*k+2]);
}
}
void update_gcd(int a, int b, ll x, int k, int l, int r){
eval(k, l, r);
if(r<=a || b<=l || x%vlcm[k]==0) return;
if(a<=l && r<=b && mx[k]*(r-l)==sum[k]){
lazy[k]=gcd(x, mx[k]);
eval(k, l, r);
}else{
update_gcd(a, b, x, 2*k+1, l, (l+r)/2);
update_gcd(a, b, x, 2*k+2, (l+r)/2, r);
mx[k]=max(mx[2*k+1], mx[2*k+2]);
sum[k]=sum[2*k+1]+sum[2*k+2];
vlcm[k]=lcm(vlcm[2*k+1], vlcm[2*k+2]);
}
}
ll max_query(int a, int b, int k, int l, int r){
eval(k, l, r);
if(r<=a || b<=l) return 0;
if(a<=l && r<=b) return mx[k];
else return max(max_query(a, b, 2*k+1, l, (l+r)/2), max_query(a, b, 2*k+2, (l+r)/2, r));
}
ll sum_query(int a, int b, int k, int l, int r){
eval(k, l, r);
if(r<=a || b<=l) return 0;
if(a<=l && r<=b) return sum[k];
else return sum_query(a, b, 2*k+1, l, (l+r)/2)+sum_query(a, b, 2*k+2, (l+r)/2, r);
}
int main()
{
int q; cin>>n>>q;
for(int i=0; i<n; i++) cin>>a[i];
init();
for(int i=0; i<q; i++){
int t, l, r; cin>>t>>l>>r;
ll x;
if(t<=2) cin>>x;
if(t==1) update(l-1, r, x, 0, 0, sz);
else if(t==2) update_gcd(l-1, r, x, 0, 0, sz);
else if(t==3) cout<<max_query(l-1, r, 0, 0, sz)<<endl;
else cout<<sum_query(l-1, r, 0, 0, sz)<<endl;
}
return 0;
}
chocorusk