HDOJ4267解题报告

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了HDOJ4267解题报告相关的知识,希望对你有一定的参考价值。

题目地址:http://acm.hdu.edu.cn/showproblem.php?pid=4267

题目概述:

  略。

大致思路:

  RMQ问题。刚开始其实是懵逼的,想了好久add操作怎么写,后来发现k其实很小,所以其实add总共只有55种情况(每个k及它所对应的余数)。

  然后会发现用二维数组来存所有的情况会MLE,hhhhh。一顿死抠内存仍然是MLE。然后经过大神指点发现可以用一维数组来存所有状况,最后记得初始化状态数组。

代码:

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <vector>
#include <ctime>
#include <map>
#include <queue>
#include <cstring>
#include <algorithm>
using namespace std;

#define sacnf scanf
#define scnaf scanf
#define maxn 50010
#define maxm 26
#define inf 1061109567
#define Eps 0.001
const double PI=acos(-1.0);
#define mod 1000000007
#define MAXNUM 10000
void Swap(int &a,int &b) {int t=a;a=b;b=t;}
int Abs(int x) {return (x<0)?-x:x;}
typedef long long ll;
typedef unsigned int uint;

struct node
{
    int sum[57];
    int val;
} tree[4*maxn];

void build_tree(int l,int r,int dir)
{
    memset(tree[dir].sum,0,sizeof(tree[dir].sum));
    if(l==r)
    {
        scnaf("%d",&tree[dir].val);
        return;
    }
    int m=(l+r)>>1;
    build_tree(l,m,dir*2);
    build_tree(m+1,r,dir*2+1);
}

int query(int l,int r,int dir,int x)
{
    if(l>x||r<x) return 0;
    int ans=0;
    for(int i=1;i<=10;i++)
        for(int j=0;j<i;j++)
            if((x-l+j)%i==0) ans+=tree[dir].sum[i*(i-1)/2+j];
    if(l==r) return ans+=tree[dir].val;
    int m=(l+r)>>1;
    ans+=query(l,m,dir*2,x);
    ans+=query(m+1,r,dir*2+1,x);
    return ans;
}

void Add(int l,int r,int dir,int al,int ar,int k,int c)
{
    if(l>=al&&r<=ar)
    {
        tree[dir].sum[k*(k-1)/2+(l-al)%k]+=c;
        return;
    }
    if(al>r||ar<l) return;
    int m=(l+r)>>1;
    Add(l,m,dir*2,al,ar,k,c);
    Add(m+1,r,dir*2+1,al,ar,k,c);
}

int main()
{
    //freopen("data.in","r",stdin);
    //freopen("data.out","w",stdout);
    //clock_t st=clock();
    int n,opt;
    while(~scanf("%d",&n))
    {
        build_tree(1,n,1);
        int m,a,b,k,c;
        scnaf("%d",&m);
        while(m--)
        {
            scanf("%d",&opt);
            if(opt==1)
            {
                scanf("%d%d%d%d",&a,&b,&k,&c);
                Add(1,n,1,a,b,k,c);
            }
            else if(opt==2)
            {
                scanf("%d",&a);
                printf("%d\n",query(1,n,1,a));
            }
        }
    }
    //clock_t ed=clock();
    //printf("\n\nTime Used : %.5lf Ms.\n",(double)(ed-st)/CLOCKS_PER_SEC);
    return 0;
}

 

以上是关于HDOJ4267解题报告的主要内容,如果未能解决你的问题,请参考以下文章

HDOJ1058解题报告

HDOJ6269解题报告

HDOJ2058解题报告

HDOJ2242解题报告边双连通分量

HDOJ3555解题报告

HDOJ1811解题报告