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 }

你可能感兴趣的:(root)