zoukankan      html  css  js  c++  java
  • codevs1081 线段树练习 2

    题目描述 Description

    给你N个数,有两种操作


    1:给区间[a,b]的所有数都增加X


    2:询问第i个数是什么?

    输入描述 Input Description

    第一行一个正整数n,接下来n行n个整数,再接下来一个正整数Q,表示操作的个数. 接下来Q行每行若干个整数。如果第一个数是1,后接3个正整数a,b,X,表示在区间[a,b]内每个数增加X,如果是2,后面跟1个整数i, 表示询问第i个位置的数是多少。

    输出描述 Output Description

    对于每个询问输出一行一个答案

    样例输入 Sample Input

    3

    1

    2

    3

    2

    1 2 3 2

    2 3

    样例输出 Sample Output

    5

    数据范围及提示 Data Size & Hint

    数据范围

    1<=n<=100000

    1<=q<=100000

     
    #include<bits/stdc++.h>
    using namespace std;
    int k,n,q,A[1000010],v,addv[1000010],_sum,a,b,loc;
    
    void Buildtree(){
    	for(int i=(1<<k)-1;i>0;i--)A[i]=A[i*2]+A[i*2+1];
    }
    
    void update(int L,int R,int o){
    	if(a<=L && R<=b)addv[o]+=v;
    	else{
    		int M=L+(R-L)/2;
    		if(M>=a)update(L,M,o*2);
    		if(M<b)update(M+1,R,o*2+1);
    	}
    }
    
    void query(int L,int R,int o){
    	if(L==R)_sum=_sum+addv[o]+A[o];
    	else{
    		_sum+=addv[o];
    		int M=L+(R-L)/2;
    		if(M>=loc)query(L,M,o*2);
    		else query(M+1,R,o*2+1);
    	}
    }
    
    int main(){
    	cin>>n;
    	while(1<<k<n)k++;
    	for(int i=1<<k;i<=(1<<k)+n-1;i++)scanf("%d",&A[i]);
    	Buildtree();
    	cin>>q;
    	while(q--){
    		int x;
    		scanf("%d",&x);
    		if(x==1){
    			scanf("%d%d%d",&a,&b,&v);
    			update(1,1<<k,1);
    		}
    		else{
    			_sum=0;
    			scanf("%d",&loc);
    			query(1,1<<k,1);
    			cout<<_sum<<endl;
    		}
    	}
    	return 0;
    }
  • 相关阅读:
    jQuery 入门 -- 事件 事件绑定与事件委托
    原生js实现视差风格音乐播放器
    jQuery 入门
    一些开放的免费接口【已失效】
    php mysqli操作数据库
    DOM 相关
    面向对象
    对象
    博客园添加鼠标点击特效
    正则表达式
  • 原文地址:https://www.cnblogs.com/codetogether/p/7066633.html
Copyright © 2011-2022 走看看