CS Academy Round #30 (Div. 2 only) C.Constant Sum(树状数组,区间修改,单点查询模板)

64 篇文章 0 订阅
50 篇文章 0 订阅

Constant Sum

Time limit:  1000 ms
Memory limit:  128 MB

You have an array AA of NN integers. You have to perform QQ operations of two types:

  1. Update: given two integers ii and ss, add ss to A_iAi and decrease all the other elements of AA by \large\frac{s}{N-1}N1s.
  2. Query: given an index i find the value of A_iAi.

Standard input

The first line contains two integers NN and QQ.

The second line contains the NN elements of AA.

Each of the following QQ lines describes one operation. An update consists of three integers 0\ i\ s0 i s, while a query consists of two inters 1\ i1 i.

Standard output

For each query print the answer on a distinct line.

Constraints and notes

  • 2 \leq N\leq 10^52N105 
  • 1 \leq Q \leq 10^51Q105 
  • 0 \leq A_i \leq 10000Ai1000 
  • 1 \leq s_i \leq 10001si1000 
  • An answer is considered correct if the absolute difference between it and the official answer is less than 10^{-6}106.

题目大意:在n个数字的数组中进行一下两种操作
1.在i位置增加s,同时减少除他外其他每个点s/(n-1)
2.查询i点的值
解题思路:这道题是一道典型的用树状数组进行区间修改单点查询的题
在这种题的背景下,对i这个位置增加x进行单点修改的时候,要将i之后的所有位置减去-x,这样可保证在单点查询的时候,直接查询i即可
这是与之前正常的区间查询单点修改不同的,同时在区间修改的时候,若是[x,y]这个区间修改,则在x这个位置进行加值操作,在y+1这个位置进行减小操作,这样就可以保证在[x,y]这个范围内进行了修改


Input Output
4 6
1 2 4 3
0 2 6
1 1
0 1 3
1 3
0 1 2
1 4
-1.0000000000
1.0000000000
-0.6666666667
#include<iostream>    
#include<cstdio>  
#include<stdio.h>  
#include<cstring>    
#include<cstdio>    
#include<climits>    
#include<cmath>   
#include<vector>  
#include <bitset>  
#include<algorithm>    
#include <queue>  
#include<map> 
#define inf 9999999; 
using namespace std;

int n,T;
double a[100005];
int lowbit(int x)
{
	return x&(-x);
}
void update(int x,double y)
{
	while(x<=n)
	{
		a[x]+=y;
		x+=lowbit(x);
	}
}
double query(int x)
{
	double ans=0;
	while(x>0)
	{
		ans+=a[x];
		x-=lowbit(x);
	}
	return ans;
}
int main()
{
	int i,k;
	int x;
	double y;
	cin>>n>>T;
	for(i=1;i<=n;i++)
	{
		cin>>y;
		update(i,y);
		update(i+1,-y);
	}
	while(T--)
	{
		cin>>k;
		if(k==0)
		{
			cin>>x>>y;
			update(x,y);
			update(x+1,-y);
			update(1,-y/(n-1));
			update(x,y/(n-1));
			update(x+1,-y/(n-1));
		}
		else
		{
			cin>>x;
			printf("%0.10lf\n",query(x));
		}
	}
}


 
 
 
 
 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值