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;
    }
  • 相关阅读:
    sqlserver tips
    mysql tips
    小知识点集锦
    设计模式
    将微博或者qq空间的说说同步至博客园 wcf+js(ajax)跨域请求(1)
    WCF服务寄宿IIS与Windows服务
    C# 基础小知识之yield 关键字
    WPF命令绑定 自定义命令
    KnockOut 绑定之foreach绑定(mvc+knockout)
    P5019 铺设道路
  • 原文地址:https://www.cnblogs.com/codetogether/p/7066633.html
Copyright © 2011-2022 走看看