您的位置:首页 > 其它

URAL 2062 Ambitious Experiment(树状数组)

2016-08-23 21:43 447 查看
题目地址:http://acm.timus.ru/problem.aspx?space=1&num=2062
思路:对于x位置上的数,对其有贡献的数为位置为x的因数且属于修改区间[l,r]的数。所以对于查询操作ans=a[p]+sigma(sum(j)) (j为p的约数)。区间修改时仅需修改区间端点值:c[l]+=d,c[r+1]-=d(当数x在某个无重复区间[l,r]时,每次求前x项的和时已包含该区间即已加上该数贡献,当x>r时,求前x项和时,该区间和为0,即数x贡献为0)。

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
typedef long long LL;
const int maxn=3e5+50;
int n,q;
LL c[maxn],a[maxn];
int lowbit(int x)
{
return x&(-x);
}
void add(int x,int w)
{
while(x<=n)
{
c[x]+=w;
x+=lowbit(x);
}
}
LL sum(int x)
{
LL tot=0;
while(x)
{
tot+=c[x];
x-=lowbit(x);
}
return tot;
}
int main()
{
scanf("%d",&n);
for(int i=1; i<=n; i++)
scanf("%d",&a[i]);
scanf("%d",&q);
while(q--)
{
int id;
scanf("%d",&id);
if(id==2)
{
int l,r,w;
scanf("%d%d%d",&l,&r,&w);
add(l,w);
add(r+1,-w);
}
else
{
int p;
scanf("%d",&p);
LL ans=a[p];
for(int i=1; i*i<=p; i++)
{
if(p%i) continue;
ans+=sum(i);
if(i!=p/i) ans+=sum(p/i);
}
printf("%I64d\n",ans);
}
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  URAL 树状数组