10ptsWA线段树求助
查看原帖
10ptsWA线段树求助
1112408
2024ing楼主2024/7/26 19:45
#include<bits/stdc++.h>
using namespace std;
const int N=5e3+7;
typedef long long ll;
int n;
ll lable[N];
class Binary_Line_Tree{
	public:
		void check_output(){
			for(int i=1;i<=tot+4;i++){
				printf("id:%d %d~%d:%d(%d)\n",i,k[i].left_lim,k[i].right_lim,k[i].sum,k[i].lazytag);
			}
		}
		void build_tree(ll place,ll l,ll r){
			++tot;
		//add son
			k[place].left_lim=l;
			k[place].right_lim=r;
		//solve single leaf
			if(l==r){
				k[place].sum=lable[l];
				return;
			}
			ll mid=(l+r)>>1;
		//add left tree
			build_tree(left_son(place),l,mid);
		//add right tree
			build_tree(right_son(place),mid+1,r);
		//solve the sum of the certain tree part
		//put it here to get the answer from the last level
			k[place].sum=k[left_son(place)].sum+k[right_son(place)].sum;
		}
		void add_tree_double(int place,int l,int r,int add_num){
		//use "lazytag" to solve it
		//only add when asked
		
		//just add when included
			if(be_in_check(l,r,k[place].left_lim)&&be_in_check(l,r,k[place].right_lim)==true){
			//add=add_number*(num_of_things)=add_number*(r-l+1)
				k[place].sum+=add_num*(k[place].right_lim-k[place].left_lim+1);
			//solve lazytag(in fact it is just a thing like a TIMEMARK)
				k[place].lazytag+=add_num;
				return;
			}
		//lazytag+push_down=yyds
		//warn:it is in private
			push_down(left_son(place));
			if(be_in_check(l,r,k[left_son(place)].left_lim)||be_in_check(l,r,k[left_son(place)].right_lim)){
				add_tree_double(left_son(place),l,r,add_num);
			}
			if(be_in_check(l,r,k[right_son(place)].left_lim)||be_in_check(l,r,k[right_son(place)].right_lim)){
				add_tree_double(right_son(place),l,r,add_num);
			}
		//solve sum
			k[place].sum=k[left_son(place)].sum+k[right_son(place)].sum;
		}
		ll search_tree_double(ll place,ll l,ll r){
	//		printf("search id:%d\n",place);
			if(be_in_check(l,r,k[place].left_lim)&&be_in_check(l,r,k[place].right_lim)==true){
	//			printf("here ans:%d\n",k[place].sum);
				return k[place].sum;
			}
			if((be_in_check(k[place].left_lim,k[place].right_lim,l)||be_in_check(k[place].left_lim,k[place].right_lim,r))==false){
	//			printf("[%lld %lld]\n",l,r);
				return 0;
			}
			push_down(place);
			ll ans=0;
			if(be_in_check(l,r,k[left_son(place)].left_lim)||be_in_check(l,r,k[left_son(place)].right_lim)==true){
				ans+=search_tree_double(left_son(place),l,r);
			}
			if(be_in_check(l,r,k[right_son(place)].left_lim)||be_in_check(l,r,k[right_son(place)].right_lim)==true){
				ans+=search_tree_double(right_son(place),l,r);
			}
	//		printf("ans:%d\n",ans);
			return ans;
		}
	private:
		struct tree_node{
			int left_lim,right_lim,sum,lazytag;
		}k[N*4];
		ll left_son(ll x){return x*2;}
		ll right_son(ll x){return x*2+1;}
		ll tot=0;
		bool be_in_check(ll l,ll r,ll asked){
			return (asked>=l)&&(asked<=r);
		}
		// lazytag is so lazy that it only pushes one level 
		void push_down(ll place){
		//avoid no use adding
			if(k[place].lazytag==0)return;
		//push the lazytag
			k[left_son(place)].lazytag+=k[place].lazytag;
			k[right_son(place)].lazytag+=k[place].lazytag;
		//solve sum
			k[left_son(place)].sum+=k[place].lazytag*(k[left_son(place)].right_lim-k[left_son(place)].left_lim+1);
			k[right_son(place)].sum+=k[place].lazytag*(k[right_son(place)].right_lim-k[right_son(place)].left_lim);//-(mid+1)+1 -> -mid
		//erase lazytag
			k[place].lazytag=0;
			return;
		}
};
int main(){
	int m,op,x,k,y;
	scanf("%d%d",&n,&m);
	for(int i=1;i<=n;i++)scanf("%lld",&lable[i]);
	Binary_Line_Tree tree;
	tree.build_tree(1,1,n);
	while(m--){
		tree.check_output();
		scanf("%d",&op);
		if(op==1){
			scanf("%d%d%d",&x,&y,&k);
			tree.add_tree_double(1,x,y,k);
		}else{
			scanf("%d%d",&x,&y);
			ll ans=tree.search_tree_double(1,x,y);
			printf("%lld\n",ans);
		}
	}
	return 0;
}
2024/7/26 19:45
加载中...