結果

問題 No.1000 Point Add and Array Add
ユーザー 沙耶花沙耶花
提出日時 2020-02-28 21:46:55
言語 C++17
(gcc 12.3.0 + boost 1.83.0)
結果
AC  
実行時間 414 ms / 2,000 ms
コード長 3,330 bytes
コンパイル時間 2,148 ms
コンパイル使用メモリ 209,824 KB
実行使用メモリ 16,688 KB
最終ジャッジ日時 2024-10-13 17:13:07
合計ジャッジ時間 6,911 ms
ジャッジサーバーID
(参考情報)
judge3 / judge2
このコードへのチャレンジ
(要ログイン)

テストケース

テストケース表示
入力 結果 実行時間
実行使用メモリ
testcase_00 AC 2 ms
5,248 KB
testcase_01 AC 2 ms
5,248 KB
testcase_02 AC 2 ms
5,248 KB
testcase_03 AC 2 ms
5,248 KB
testcase_04 AC 1 ms
5,248 KB
testcase_05 AC 2 ms
5,248 KB
testcase_06 AC 1 ms
5,248 KB
testcase_07 AC 1 ms
5,248 KB
testcase_08 AC 2 ms
5,248 KB
testcase_09 AC 2 ms
5,248 KB
testcase_10 AC 2 ms
5,248 KB
testcase_11 AC 2 ms
5,248 KB
testcase_12 AC 4 ms
5,248 KB
testcase_13 AC 3 ms
5,248 KB
testcase_14 AC 5 ms
5,248 KB
testcase_15 AC 4 ms
5,248 KB
testcase_16 AC 272 ms
16,128 KB
testcase_17 AC 231 ms
9,984 KB
testcase_18 AC 389 ms
16,688 KB
testcase_19 AC 384 ms
16,560 KB
testcase_20 AC 388 ms
16,640 KB
testcase_21 AC 350 ms
16,624 KB
testcase_22 AC 414 ms
16,640 KB
testcase_23 AC 360 ms
16,676 KB
権限があれば一括ダウンロードができます

ソースコード

diff #

#include <bits/stdc++.h>
using namespace std;
#define modulo 1000000007
#define mod(mod_x) ((((long long)mod_x+modulo))%modulo)
#define Inf 10000000000000000

template <typename T1,typename T2>
struct lazysegtree{
	//元データx[i]はv[n+i]
	//v[i]の親はv[i/2],子はv[i*2]とv[i*2+1]
	vector<T1> v1;
	vector<T2> v2;
	vector<int> sz_;
	int n;
	int cnt;
	
	const T1 init_value1 = 0;
	const T2 init_value2 = 0;
	
	lazysegtree(int sz){
		n=1;
		cnt=0;
		while(true){
			if(n>=sz)break;
			n*=2;
			cnt++;
		}
		v1.resize(2*n,init_value1);
		v2.resize(2*n,init_value2);

		for(int i=n-1;i>=0;i--){
			v1[i]=func1(v1[i*2],v1[i*2+1]);
		}
		
		sz_.resize(2*n,n);
		
		for(int i=2;i<2*n;i++){
			sz_[i] = sz_[i/2]/2;
		}
		
	}
	
	lazysegtree(vector<T1> &x){
		n=1;
		cnt=0;
		while(true){
			if(n>=x.size())break;
			n*=2;
			cnt++;
		}
		v1.resize(2*n,init_value1);
		v2.resize(2*n,init_value2);
		for(int i=0;i<x.size();i++){
			v1[n+i]=x[i];
		}
		for(int i=n-1;i>=0;i--){
			v1[i]=func1(v1[i*2],v1[i*2+1]);
		}
		
		sz_.resize(2*n,n);
		
		for(int i=2;i<2*n;i++){
			sz_[i] = sz_[i/2]/2;
		}
		
	}

	//2人の子供に伝える
	void propagate(int ind){
		update(ind*2,v2[ind]);
		update(ind*2+1,v2[ind]);
		v2[ind] = init_value2;
	}
	
	//あるノードに対し先祖から伝播
	void reflect(int ind){
		for(int j=cnt;j>=1;j--){
			propagate(ind>>j);
		}
	}
	
	//子供の値を親に伝える
	void mergeChildren(int ind){
		v1[ind] = func2(func1(v1[ind*2],v1[ind*2+1]),v2[ind],sz_[ind]);
	}
	
	//ある要素について作用させる
	void update(int ind,T2 x){
		v1[ind] = func2(v1[ind],x,sz_[ind]);
		v2[ind] = func2(v2[ind],x,1);
	}
	
	//[l,r)に対して作用させる
	void update(int l,int r,T2 x){
		if(l>=r)return;
		int L = l,R = r;
		l+=n;
		r+=n;
		reflect(l);
		reflect(r-1);
		while(true){
			if(l%2==1){
				update(l,x);
				l++;
			}
			if(r%2==1){
				update(r-1,x);
				r--;
			}
			if(l>=r)break;
			l/=2;
			r/=2;
		}
		
		l = L + n;
		r = R + n;
		
		while(true){
			l/=2;
			r=(r+1)/2;
			if(l<=0)break;
			mergeChildren(l);
			mergeChildren(r-1);
		}
		
	}
	
	//区間[l,r)におけるクエリ処理
	T1 query(int l,int r){
		T1 res1 = init_value1;
		T1 res2 = init_value1;
		if(l>=r)return res1;
		l+=n;
		r+=n;
		reflect(l);
		reflect(r-1);
		while(true){
			if(l%2==1){
				res1=func1(res1,v1[l]);
				l++;
			}
			if(r%2==1){
				res2=func1(v1[r-1],res2);
				r--;
			}
			if(l>=r)break;
			l/=2;r/=2;
		}
		return func1(res1,res2);
	}
	
	T1 func1(T1 a,T1 b){
		return a+b;
	}
	
	T1 func2(T1 a,T2 b,long long sz){
		return a+b*sz;
	}

	void show(){
		int n = 1;
		for(int i=1;i<v1.size();i++){
			for(int j=0;j<n;j++){
				if(j!=0)cout<<' ';
				cout<<v1[i+j];
			}
			cout<<endl;
			i+=n-1;
			n*=2;
		}
	}
	
};

int main(){
	
	int N,Q;
	cin>>N>>Q;
	
	lazysegtree<long long,long long> seg(N);
	
	vector<long long> A(N);
	
	for(int i=0;i<N;i++){
		cin>>A[i];
	}
	
	vector<long long> B(N,0);
	
	for(int i=0;i<Q;i++){
		char c;
		cin>>c;
		
		long long x,y;
		cin>>x>>y;
		
		if(c=='A'){
			x--;
			long long D = seg.query(x,x+1);
			B[x] += D*A[x];
			seg.update(x,x+1,-D);
			A[x] += y;
		}
		else{
			x--;y--;
			seg.update(x,y+1,1);
		}
	}
	
	for(int i=0;i<N;i++){
		B[i] += seg.query(i,i+1)*A[i];
	}
	
	for(int i=0;i<N;i++){
		if(i!=0)cout<<' ';
		cout<<B[i];
	}
	cout<<endl;

	return 0;
}
0