HDU 4351 DigitalRoot

View Code
  1 //Result:2012-08-12 13:44:40    Accepted    4351    812MS    11016K    3495 B    C++    Wizmann
  2 #include <cstdio>
  3 #include <cstring>
  4 #include <algorithm>
  5 #include <iostream>
  6 #include <algorithm>
  7 
  8 using namespace std;
  9 
 10 #define print(x) cout<<x<<endl
 11 #define input(x) cin>>x
 12 #define SIZE 100100
 13 #define FORCE 1024
 14 
 15 inline int left(int x){return (x<<1)+1;}
 16 inline int right(int x){return (x<<1)+2;}
 17 
 18 struct node
 19 {
 20     int l,r,val;
 21     int now,lson,rson;
 22     node(){}
 23     node(int il,int ir)
 24     {
 25         l=il;r=ir;
 26         val=now=lson=rson=0;
 27     }
 28     inline void init(int ival)
 29     {
 30         val=now=lson=rson=(1<<ival);
 31     }
 32     inline int getmid(){return (l+r)>>1;}
 33     inline int equal(int il,int ir){return l==il&&r==ir;}
 34     inline int has_next(){return l!=r;}
 35 };
 36 
 37 struct result
 38 {
 39     int val,now,lson,rson;
 40     result(){}
 41     result(int ival,int inow,int ilson,int irson)
 42     {
 43         val=ival;
 44         now=inow;
 45         lson=ilson;
 46         rson=irson;
 47     }
 48 };
 49 
 50 node stree[SIZE*3];
 51 int n;
 52 int k[SIZE];
 53 int mp[FORCE+10][FORCE+10];
 54 const int ROOT=0;
 55 
 56 void init()
 57 {
 58     for(int i=0;i<FORCE;i++)
 59     {
 60         for(int j=0;j<FORCE;j++)
 61         {
 62             for(int a=0;a<=9;a++) if(i&(1<<a))
 63             {
 64                 for(int b=0;b<=9;b++) if(j&(1<<b))
 65                 {
 66                     int val=(a+b-1)%9+1; 
 67                     mp[i][j]|=(1<<val);
 68                 }
 69             }
 70         }
 71     }
 72 }
 73 
 74 void stree_init(int l,int r,int pos=ROOT)
 75 {
 76     stree[pos]=node(l,r);
 77     if(l==r) stree[pos].init(k[l]);
 78     else if(l<r)
 79     {
 80         int mid=(l+r)>>1;
 81         stree_init(l,mid,left(pos));
 82         stree_init(mid+1,r,right(pos));
 83 
 84         stree[pos].val=mp[stree[left(pos)].val][stree[right(pos)].val];
 85         stree[pos].lson=stree[left(pos)].lson \
 86                             | mp[stree[left(pos)].val][stree[right(pos)].lson];
 87         stree[pos].rson=stree[right(pos)].rson \
 88                             | mp[stree[right(pos)].val][stree[left(pos)].rson];
 89         stree[pos].now=stree[left(pos)].now \
 90                         | stree[right(pos)].now \
 91                         | mp[stree[left(pos)].rson][stree[right(pos)].lson];
 92     }
 93 }
 94 
 95 result stree_query(int l,int r,int pos=ROOT)
 96 {
 97     if(stree[pos].equal(l,r))
 98     {
 99         return result(stree[pos].val,stree[pos].now,stree[pos].lson,stree[pos].rson);
100     }
101     else
102     {
103         int mid=stree[pos].getmid();
104         if(r<=mid) return stree_query(l,r,left(pos));
105         else if(l>mid) return stree_query(l,r,right(pos));
106         else
107         {
108             result a=stree_query(l,mid,left(pos));
109             result b=stree_query(mid+1,r,right(pos));
110 
111             int val=mp[a.val][b.val];
112             //val代表[l,r]区间的DigitalRoot
113             //mp[a.val][b.val],由于a.val和b.val都只有一个"1"位,所以mp[a.val][b.val]==DigitalRoot(a+b),也只有一位
114             int lson=a.lson | mp[a.val][b.lson];
115             //lson是指[l,r]区间的前辍,由a(左边)的lson与a.val与b.lson的和组成
116             int rson=b.rson | mp[a.rson][b.val];
117             //同上
118             int now = a.now | b.now | mp[a.rson][b.lson];
119             //now代表当前区间能表示的DigitalRoot的种类数
120             //a.now | b.now 父节点是继承子节点的可行值(这个好理解)
121             //mp[a.rson][b.lson]是指在[l,r]的中点mid处,[...mid][mid...]这种类型的合并
122             
123             return result(val,now,lson,rson);
124         }
125     }
126 }
127 
128 
129 int main()
130 {
131     
132     int T,a,b,q;
133     input(T);
134     init();
135     int res[10];
136     int cas=1;
137     while(T--)
138     {
139         printf("Case #%d:\n",cas++);
140         input(n);
141         for(int i=1;i<=n;i++)
142         {
143             scanf("%d",&a);
144             k[i]=(a-1)%9+1;
145         }
146         stree_init(1,n);
147         input(q);
148         while(q--)
149         {
150             scanf("%d%d",&a,&b);
151             result r=stree_query(a,b);
152             int ptr=0,val=9;
153             memset(res,-1,sizeof(res));
154             while(ptr<5 && val>=0)
155             {
156                 if(r.now & (1<<val))
157                 {
158                     res[ptr++]=val;
159                 }
160                 val--;
161             }
162             for(int i=0;i<5;i++)
163             {
164                 if(i) printf(" ");
165                 printf("%d",res[i]);
166             }
167             puts("");
168         }
169         if(T) puts("");
170     }
171     return 0;
172 }

posted on 2012-08-12 13:45  Wizmann  阅读(266)  评论(0编辑  收藏  举报

导航