zoukankan      html  css  js  c++  java
  • hdu4267 线段树

     开始敲了一发线段树,觉得可以暴力一点的过,tle了。后来进行修改,发现了问题。

    后来一看大神的做法,由于1<=k<=10,所以对于不同的k,有55个余,找答案的时候只要找不同的k值满足条件的值。

    成段更新时,更新全部的树即可。

    #include<stdio.h>
    #include<string.h>
    #define lson l,m,rt<<1
    #define rson m+1,r,rt<<1|1
    const int maxn = 50010;
    int sum[55][maxn<<2],mark[maxn<<2],set[11],F[maxn];
    void build(int l,int r,int rt)
    {
        for(int i=0;i<55;i++)
            sum[i][rt]=0;
        mark[rt]=0;
        if(l==r)
        {
            return;
        }
        int m=(l+r)/2;
        build(lson);
        build(rson);
    }
    void pushdown(int l,int r,int rt)
    {
        if(mark[rt])
        {
            mark[rt<<1]=mark[rt<<1|1]=mark[rt];
            for(int i=0;i<55;i++)
            {
                sum[i][rt<<1]+=sum[i][rt];
                sum[i][rt<<1|1]+=sum[i][rt];
                sum[i][rt]=0;
            }
            mark[rt]=0;
        }
    }
    void updata(int a,int b,int k,int c,int l,int r,int rt)
    {
        if(l>=a&&b>=r)
        {
            int t=set[k-1]+a%k;//由于(i-a)%k==0-->i%k==a%k 
            mark[rt]=1;
            sum[t][rt]+=c;
            return ;
        }
        int m=(l+r)/2;
        if(m>=a)
            updata(a,b,k,c,lson);
        if(m<b)
            updata(a,b,k,c,rson);
    }
    int query(int p,int l,int r,int rt)
    {
        if(l==r)
        {
            int ans=0;
            for(int i=1;i<=10;i++)
                ans+=sum[p%i+set[i-1]][rt];
            return ans;
        }
        pushdown(l,r,rt);
        int m=(l+r)/2;
        if(m>=p)
            return query(p,lson);
        else 
            return query(p,rson);
    }
    int main()
    {
        int i,n;
        set[0]=0;
        for(i=1;i<=10;i++)
            set[i]=i+set[i-1];
        while(~scanf("%d",&n))
        {
            build(1,n,1);
            for(i=1;i<=n;i++)
                scanf("%d",&F[i]);
            int t;
            scanf("%d",&t);
            while(t--)
            {
                int m;
                scanf("%d",&m);
                if(m==1)
                {
                    int a,b,k,c;
                    scanf("%d%d%d%d",&a,&b,&k,&c);
                    updata(a,b,k,c,1,n,1);
                }
                else
                {
                    int p;
                    scanf("%d",&p);
                    printf("%d
    ",query(p,1,n,1)+F[p]);
                }
            }
        }
    }
  • 相关阅读:
    多线程GCD(二)
    多线程
    Runtime & Runloop
    MTK android 重启测试脚本
    ubuntu samba 配置简介
    Gerrit使用简介
    MTK andorid从底层到上层添加驱动
    MTK GPIO 新增变量配置
    MT6755 使用R63350 IC 出现唤醒概率性闪白,并导致ESD FAIL
    android L版本AAL新架构
  • 原文地址:https://www.cnblogs.com/sweat123/p/4907917.html
Copyright © 2011-2022 走看看