hdu4351

这道题我感觉应该用线段树来做,写了之后还是超时,别的优化方法想不到了,欢迎各位指教

(补充一点优化的方法,第一求root digit的时候可以直接对9取余,如果是9的倍数,那么直接就是9,第二在build的时候在最后面加这样一句话:if(b[i].sum>9) b[i].sum-=9;)

  1 #include <stdio.h>
  2 #include <string.h>
  3 #include <algorithm>
  4 using namespace std;
  5 int a[100005];
  6 int res[100005*4];
  7 struct node
  8 {
  9     int left,right,sum;
 10 }b[100005*4];
 11 
 12 int abc(int a)
 13 {
 14     int sum=0;
 15     while(a>0)
 16     {
 17         sum=sum+a%10;
 18         a=a/10;
 19     }
 20     if(sum<=9) return sum;
 21     else return abc(sum);
 22 }
 23 
 24 int cmp(int a,int b)
 25 {
 26     return a>b;
 27 }
 28 
 29 void build(int left,int right,int i)
 30 {
 31     int mid;
 32     b[i].left=left;
 33     b[i].right=right;
 34     if(left==right)
 35     {
 36         b[i].sum=a[left];
 37         return ;
 38     }
 39 
 40     mid=(left+right)/2;
 41     build(left,mid,2*i);
 42     build(mid+1,right,2*i+1);
 43     b[i].sum=b[2*i].sum+b[2*i+1].sum;
 44 
 45 }
 46 
 47 
 48 int Query(int left, int right,int i)
 49 {
 50     int mid;
 51     if(b[i].left==left && b[i].right ==right) return b[i].sum;
 52     mid=(b[i].left+b[i].right)/2;
 53     if(right<=mid) return Query(left,right,2*i);
 54     else if (left>mid ) return Query(left,right,2*i+1);
 55     else return Query(left,mid,2*i) + Query(mid+1,right,2*i+1);
 56 }
 57 
 58 
 59 int main()
 60 {
 61     int Case;
 62     int n;
 63     scanf("%d",&Case);
 64     //int id,num;
 65     int count;
 66     int i;
 67     int k=1,j;
 68     int start ,end;
 69     int mount,index;
 70     while(Case--)
 71     {
 72         count=0;
 73         scanf("%d",&n);
 74         for(i=1;i<=n;i++)
 75         {
 76             scanf("%d",&a[i]);
 77             a[i]=abc(a[i]);
 78         }
 79         build(1,n,1);
 80         int q;
 81         printf("Case #%d:\n",k++);
 82         scanf("%d",&q);
 83         for(i=0;i<q;i++)
 84         {
 85             count=0;
 86             scanf("%d%d",&start,&end);
 87             for(j=start;j<=end;j++)
 88             {
 89                 for(k=j;k<=end;k++)
 90                 res[count++]=abc(Query(j,k,1));
 91 
 92             }
 93             sort(res,res+count,cmp);
 94             mount=0;
 95             for(index=0;mount!=5 && index<count;index++)
 96             {
 97                 if(res[index]==res[index-1]) continue;
 98                 {
 99                     printf("%d ",res[index]);
100                     mount++;
101                 }
102             }
103             for(index=0;index<5-mount;index++)
104             {
105                 if(index<5-mount-1)
106                 printf("-1 ");
107                 else printf("-1");
108             }
109             
110             printf("\n");
111         }
112     
113         printf("\n");
114 
115     }
116     return 0;
117 }

posted on 2012-08-09 17:41  矮人狙击手!  阅读(309)  评论(0编辑  收藏  举报

导航