HDOJ4267解题报告【线段树add的转化】

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

题目概述:

  略。

大致思路:

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

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

代码:

  1 #include <iostream>
  2 #include <cstdio>
  3 #include <cstdlib>
  4 #include <cmath>
  5 #include <vector>
  6 #include <ctime>
  7 #include <map>
  8 #include <queue>
  9 #include <cstring>
 10 #include <algorithm>
 11 using namespace std;
 12 
 13 #define sacnf scanf
 14 #define scnaf scanf
 15 #define maxn 50010
 16 #define maxm 26
 17 #define inf 1061109567
 18 #define Eps 0.001
 19 const double PI=acos(-1.0);
 20 #define mod 1000000007
 21 #define MAXNUM 10000
 22 void Swap(int &a,int &b) {int t=a;a=b;b=t;}
 23 int Abs(int x) {return (x<0)?-x:x;}
 24 typedef long long ll;
 25 typedef unsigned int uint;
 26 
 27 struct node
 28 {
 29     int sum[57];
 30     int val;
 31 } tree[4*maxn];
 32 
 33 void build_tree(int l,int r,int dir)
 34 {
 35     memset(tree[dir].sum,0,sizeof(tree[dir].sum));
 36     if(l==r)
 37     {
 38         scnaf("%d",&tree[dir].val);
 39         return;
 40     }
 41     int m=(l+r)>>1;
 42     build_tree(l,m,dir*2);
 43     build_tree(m+1,r,dir*2+1);
 44 }
 45 
 46 int query(int l,int r,int dir,int x)
 47 {
 48     if(l>x||r<x) return 0;
 49     int ans=0;
 50     for(int i=1;i<=10;i++)
 51         for(int j=0;j<i;j++)
 52             if((x-l+j)%i==0) ans+=tree[dir].sum[i*(i-1)/2+j];
 53     if(l==r) return ans+=tree[dir].val;
 54     int m=(l+r)>>1;
 55     ans+=query(l,m,dir*2,x);
 56     ans+=query(m+1,r,dir*2+1,x);
 57     return ans;
 58 }
 59 
 60 void Add(int l,int r,int dir,int al,int ar,int k,int c)
 61 {
 62     if(l>=al&&r<=ar)
 63     {
 64         tree[dir].sum[k*(k-1)/2+(l-al)%k]+=c;
 65         return;
 66     }
 67     if(al>r||ar<l) return;
 68     int m=(l+r)>>1;
 69     Add(l,m,dir*2,al,ar,k,c);
 70     Add(m+1,r,dir*2+1,al,ar,k,c);
 71 }
 72 
 73 int main()
 74 {
 75     //freopen("data.in","r",stdin);
 76     //freopen("data.out","w",stdout);
 77     //clock_t st=clock();
 78     int n,opt;
 79     while(~scanf("%d",&n))
 80     {
 81         build_tree(1,n,1);
 82         int m,a,b,k,c;
 83         scnaf("%d",&m);
 84         while(m--)
 85         {
 86             scanf("%d",&opt);
 87             if(opt==1)
 88             {
 89                 scanf("%d%d%d%d",&a,&b,&k,&c);
 90                 Add(1,n,1,a,b,k,c);
 91             }
 92             else if(opt==2)
 93             {
 94                 scanf("%d",&a);
 95                 printf("%d\n",query(1,n,1,a));
 96             }
 97         }
 98     }
 99     //clock_t ed=clock();
100     //printf("\n\nTime Used : %.5lf Ms.\n",(double)(ed-st)/CLOCKS_PER_SEC);
101     return 0;
102 }

 

posted @ 2017-02-26 16:21  CtrlKismet  阅读(232)  评论(0编辑  收藏  举报