Ambitious Experiment URAL - 2062

http://acm.timus.ru/problem.aspx?space=1&num=2062

2操作就是普通区间更新 对于1操作 就看i的所有因子位置当前值是多少 再加上i位置的原始值 因为更新时每一个位置都会对它的倍数位置进行更新

又是一道卡线段树的智障题。。

#include <bits/stdc++.h>
using namespace std;
#define ll long long

vector <int> pre[300010];
ll ary[300010],sum[300010];
int n,q;

int lowbit(int x)
{
    return x&(-x);
}

ll query(int tar)
{
    ll res;
    int i;
    res=0;
    for(i=tar;i>=1;i-=lowbit(i)) res+=sum[i];
    return res;
}

void update(int tar,ll val)
{
    int i;
    for(i=tar;i<=n;i+=lowbit(i)) sum[i]+=val;
}

int main()
{
    ll ans;
    int i,j,op,l,r,d;
    scanf("%d",&n);
    for(i=1;i<=n;i++)
    {
        scanf("%lld",&ary[i]);
        for(j=1;j*j<=i;j++)
        {
            if(i%j==0)
            {
                pre[i].push_back(j);
                if(j*j!=i) pre[i].push_back(i/j);
            }
        }
    }
    scanf("%d",&q);
    while(q--)
    {
        scanf("%d",&op);
        if(op==1)
        {
            scanf("%d",&i);
            ans=0;
            for(j=0;j<pre[i].size();j++) ans+=query(pre[i][j]);
            printf("%lld\n",ans+ary[i]);
        }
        else
        {
            scanf("%d%d%d",&l,&r,&d);
            update(l,d);
            update(r+1,-d);
        }
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/sunyutian1998/article/details/82111155