HDU 4267 A Simple Problem with Integers

Posted on 2013-07-26 19:05  冰天雪域  阅读(152)  评论(0编辑  收藏  举报

思路:开始直接用标记,最后发现他们是离散的点。几乎就相当于单点更行了。欧。

为何放弃治疗。。。

最后看的是  http://blog.csdn.net/ophunter/article/details/9455723

很详细。LCM 最小公倍数学长还是很狂拽酷炫的。

哎。我已可入灵魂。

 

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#define MAXN 50005
#define lson num<<1,s,mid
#define rson num<<1|1,mid+1,e
using namespace std;

int cnt[] = {0,0,1,3,6,10,15,21,28,36,45};//记录每一个K对应的MOD的起点
int n;
int tree[MAXN*3][55];//K(1~10) 每一个K都有0~k-1的mod值  所以就是55棵线段树

void pushdown(int num,int id)
{
    if(tree[num][id])
    {
        tree[num<<1][id]+=tree[num][id];
        tree[num<<1|1][id]+=tree[num][id];
        tree[num][id]=0;
    }
}

void build(int num,int s,int e)
{
    memset(tree[num],0,sizeof(tree[num]));
    if(s==e)
    {
        int a;
        scanf("%d",&a);
        tree[num][0]=a;
        return;
    }
    int mid=(s+e)>>1;
    build(lson);
    build(rson);
}

void update(int num,int s,int e,int l,int r,int val,int id)
{
    if(l<=s && r>=e)
    {
        tree[num][id]+=val;
        return;
    }
    int mid=(s+e)>>1;
    pushdown(num,id);
    if(l<=mid)update(lson,l,r,val,id);
    if(r>mid)update(rson,l,r,val,id);
}

int query(int num,int s,int e,int tag,int id)
{
    if(s==e)
    return tree[num][id];

    int mid=(s+e)>>1;
    pushdown(num,id);
    if(tag>mid)return query(rson,tag,id);
    else if(tag<=mid)return query(lson,tag,id);
}

int main()
{
    while(scanf("%d",&n)!=EOF)
    {
        build(1,1,n);
        int op;
        scanf("%d",&op);
        while(op--)
        {
            int ope;
            scanf("%d",&ope);
            if(ope==2)
            {
                int a,ans=0;
                scanf("%d",&a);
                for(int i=1;i<=10;i++)
                {
                    int id=cnt[i] + a%i;//(i-a)%k==0 ==> i%k==a%k...
                    ans+=query(1,1,n,a,id);//线段树上记录的是ADD
                }                       
                printf("%d\n",ans);
            }
            else
            {
                int a,b,k,c;
                scanf("%d%d%d%d",&a,&b,&k,&c);
                int id = cnt[k] + a%k;//找到对应的树
                update(1,1,n,a,b,c,id);
            }
        }
    }
    return 0;
}


 

 

Copyright © 2024 冰天雪域
Powered by .NET 9.0 on Kubernetes