您的位置:首页 > 其它

hdu 4267 A Simple Problem with Integers

2013-08-27 17:31 447 查看
题意:给出一n个数,有两种操作,一种是查询第i个数,另一种是在区间[a,b]中将满足(i - a) % k == 0的值加c。

思路:用线段树搞,不过这题不是每个区间的所有值都要更新,这样的话就不太好写,每个区间可以记录两个值,一个是从这个区间的第几位开始,另一个是隔多少加c,这样的话虽然可以写,但是内存可能不太够,仔细想一想的话可以发现,只需要55种状态就够了,从第0位开始有10种状态(1~10),1有9种(2~10)……以此类推。



代码:

#include <iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<algorithm>
#include<map>
#include<queue>
#include<stack>
#include<cmath>
#include<vector>
#define inf 0x3f3f3f3f
#define Inf 0x3FFFFFFFFFFFFFFFLL
#define eps 1e-9
#define pi acos(-1.0)
using namespace std;
const int maxn=50000+10;
int sum[maxn<<2],addv[maxn<<2][55];
int state[55][2],link[10][11];
void getState()
{
    int m=0;
    for(int i=0;i<10;++i)
    {
        for(int j=i+1;j<=10;++j)
        {
            state[m][0]=i;
            state[m][1]=j;
            link[i][j]=m++;
        }
    }
}
inline void PushUp(int rt)
{
    sum[rt]=sum[rt<<1]+sum[rt<<1|1];
}
void PushDown(int l,int r,int rt)
{
    int ls=rt<<1,rs=rt<<1|1;
    int m=(l+r)>>1;
    int x,y;
    for(int i=0;i<55;++i)
    {
        if(addv[rt][i]!=0)
        {
            x=state[i][0];y=state[i][1];
            if(m-l+1>x)
            {
                addv[ls][i]+=addv[rt][i];
                sum[ls]+=((m-l-x)/y+1)*addv[rt][i];
            }
            if(r-l+1>x)
            {
                if(x>=m-l+1) x=x-(m-l+1);
                else x=y-(m-l-x)%y-1;
                if(r-m>x)
                {
                    addv[rs][link[x][y]]+=addv[rt][i];
                    sum[rs]+=((r-m-x-1)/y+1)*addv[rt][i];
                }
            }
            addv[rt][i]=0;
        }
    }
}
void build(int l,int r,int rt)
{
    memset(addv[rt],0,sizeof(addv[rt]));
    if(l==r)
    {
        scanf("%d",&sum[rt]);
        return;
    }
    int m=(l+r)>>1;
    build(l,m,rt<<1);
    build(m+1,r,rt<<1|1);
    PushUp(rt);
}
void Update(int L,int R,int l,int r,int rt,int k,int c)
{
    if(l>=L&&r<=R)
    {
        int x=(l-L);
        if(x!=0)
            x=k-(x-1)%k-1;
        if(r-l+1>x)
        {
            sum[rt]+=((r-l-x)/k+1)*c;
            addv[rt][link[x][k]]+=c;
        }
        return ;
    }
    PushDown(l,r,rt);
    int m=(l+r)>>1;
    if(m>=L)
      Update(L,R,l,m,rt<<1,k,c);
    if(m<R)
      Update(L,R,m+1,r,rt<<1|1,k,c);
    PushUp(rt);
}
int Query(int p,int l,int r,int rt)
{
    if(l==r)
        return sum[rt];
    PushDown(l,r,rt);
    int m=(l+r)>>1;
    if(m>=p)
      return Query(p,l,m,rt<<1);
    else return Query(p,m+1,r,rt<<1|1);
}
int main()
{
    //freopen("in.txt","r",stdin);
    //freopen("out.txt","w",stdout);
    int n,q;
    getState();
    while(~scanf("%d",&n))
    {
        build(1,n,1);
        scanf("%d",&q);
        int a,b,k,c,tp;
        while(q--)
        {
            scanf("%d",&tp);
            if(tp==1)
            {
                scanf("%d%d%d%d",&a,&b,&k,&c);
                Update(a,b,1,n,1,k,c);
            }
            else
            {
                scanf("%d",&a);
                int ans=Query(a,1,n,1);
                printf("%d\n",ans);
            }
        }
    }
    return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: