hdu4267

树状数组写的

真不知道线段树的怎么写额。。写了一遍TLE就不知道怎么改了→  →

 (i - a) % k == 0这个分析看题解才懂的。。

变为i%k==a%k  的形式  发现只要把c变为三维数组就行了

更新时  c[n][k][a%k]  这样就能实现区域更新了

在计算时 c[n][i][i%k]  这样就满足了 i%k==a%k 的条件  把所有满足条件的加起来就A了。。


#include <stdio.h>
#include <string.h>

const int MAXN = 50005;

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

int c[MAXN][11][11],n,a[MAXN];

void modi(int pos,int val,int k,int mod)
{
    while(pos>0)
    {
        c[pos][k][mod]+=val;
        pos-=lowbit(pos);
    }
}

int cal(int pos,int p)
{
    int sum=0;
    while(pos<=n)
    {
        for(int i=0;i<10;i++)
        {
            int k=i+1;
            sum+=c[pos][k][p%k];
        }
        pos+=lowbit(pos);
    }
    return sum;
}

int main()
{
    #ifndef ONLINE_JUDGE
        freopen("4267in.txt","r",stdin);
    #endif
    int l,r,k,val;
    while(scanf("%d",&n)==1)
    {
        memset(c,0,sizeof(c));
        for(int i=0;i<n;i++)
            scanf("%d",&a[i+1]);
        int com;
        scanf("%d",&com);
        for(int i=0;i<com;i++)
        {
            int tmp;
            scanf("%d",&tmp);
            if(tmp==1)
            {

                scanf("%d%d%d%d",&l,&r,&k,&val);
                modi(r,val,k,l%k);
                modi(l-1,-val,k,l%k);
            }
            else if(tmp==2)
            {
                scanf("%d",&l);
                printf("%d\n",cal(l,l)+a[l]);
            }
        }
    }
    return 0;
}

你可能感兴趣的:(ACM,树状数组,区间更新)