【HDOJ】4351 Digital root
digital root = n==0 ? 0 : n%9==0 ? 9:n%9;
可以简单证明一下
n = a0*n^0 + a1*n^1 + ... + ak * n^k
n%9 = a0+a1+..+ak
然后,数学归纳易知结论是正确的。
因此9个状态就够了,表示%9的结果。
这里需要特殊处理0, 表示状态为0。
1 /* 4351 */ 2 #include <iostream> 3 #include <sstream> 4 #include <string> 5 #include <map> 6 #include <queue> 7 #include <set> 8 #include <stack> 9 #include <vector> 10 #include <deque> 11 #include <algorithm> 12 #include <cstdio> 13 #include <cmath> 14 #include <ctime> 15 #include <cstring> 16 #include <climits> 17 #include <cctype> 18 #include <cassert> 19 #include <functional> 20 #include <iterator> 21 #include <iomanip> 22 using namespace std; 23 //#pragma comment(linker,"/STACK:102400000,1024000") 24 25 #define sti set<int> 26 #define stpii set<pair<int, int> > 27 #define mpii map<int,int> 28 #define vi vector<int> 29 #define pii pair<int,int> 30 #define vpii vector<pair<int,int> > 31 #define rep(i, a, n) for (int i=a;i<n;++i) 32 #define per(i, a, n) for (int i=n-1;i>=a;--i) 33 #define clr clear 34 #define pb push_back 35 #define mp make_pair 36 #define fir first 37 #define sec second 38 #define all(x) (x).begin(),(x).end() 39 #define SZ(x) ((int)(x).size()) 40 #define lson l, mid, rt<<1 41 #define rson mid+1, r, rt<<1|1 42 43 typedef struct { 44 short sum; 45 short lst, rst, st; 46 } node_t; 47 48 const int maxn = 1e5+5; 49 int zn[maxn]; 50 bool visit[10]; 51 int a[maxn]; 52 node_t nd[maxn<<2]; 53 int Mod9[105]; 54 short sum_st[20][512]; 55 short st_st[512][512]; 56 int n; 57 58 void init() { 59 rep(i, 0, 105) 60 Mod9[i] = i % 9; 61 62 rep(st, 0, 512) { 63 rep(i, 0, 20) { 64 int nst = 0; 65 66 rep(j, 0, 9) { 67 if (st & (1<<j)) { 68 int k = Mod9[i + j]; 69 nst |= (1<<k); 70 } 71 } 72 sum_st[i][st] = nst; 73 } 74 } 75 76 rep(lst, 0, 512) { 77 rep(rst, lst, 512) { 78 int nst = 0; 79 rep(i, 0, 9) { 80 if ((lst & (1<<i)) == 0) 81 continue; 82 rep(j, 0, 9) { 83 if (rst & (1<<j)) { 84 int k = Mod9[i+j]; 85 nst |= (1<<k); 86 } 87 } 88 } 89 st_st[lst][rst] = st_st[rst][lst] = nst; 90 } 91 } 92 } 93 94 95 void PushUp(int rt) { 96 int lb = rt << 1; 97 int rb = lb | 1; 98 99 nd[rt].sum = Mod9[nd[lb].sum + nd[rb].sum]; 100 nd[rt].lst = nd[lb].lst | sum_st[nd[lb].sum][nd[rb].lst]; 101 nd[rt].rst = nd[rb].rst | sum_st[nd[rb].sum][nd[lb].rst]; 102 nd[rt].st = nd[lb].st | nd[rb].st | st_st[nd[lb].rst][nd[rb].lst]; 103 } 104 105 void Build(int l, int r, int rt) { 106 if (l == r) { 107 if (zn[l] == zn[l-1]) { 108 nd[rt].sum = a[l]; 109 nd[rt].lst = nd[rt].rst = nd[rt].st = (1 << a[l]); 110 } else { 111 nd[rt].sum = a[l]; 112 nd[rt].lst = nd[rt].rst = nd[rt].st = 0; 113 } 114 return ; 115 } 116 117 int mid = (l + r) >> 1; 118 119 Build(lson); 120 Build(rson); 121 122 PushUp(rt); 123 } 124 125 node_t Query(int L, int R, int l, int r, int rt) { 126 if (L==l && R==r) { 127 return nd[rt]; 128 } 129 130 int mid = (l + r) >> 1; 131 132 if (R <= mid) { 133 return Query(L, R, lson); 134 } else if (L > mid) { 135 return Query(L, R, rson); 136 } else { 137 node_t lnd = Query(L, mid, lson); 138 node_t rnd = Query(mid+1, R, rson); 139 node_t ret; 140 141 ret.sum = Mod9[lnd.sum + rnd.sum]; 142 ret.lst = lnd.lst | sum_st[lnd.sum][rnd.lst]; 143 ret.rst = rnd.rst | sum_st[rnd.sum][lnd.rst]; 144 ret.st = lnd.st | rnd.st | st_st[lnd.rst][rnd.lst]; 145 146 return ret; 147 } 148 } 149 150 void solve() { 151 Build(1, n, 1); 152 153 int q; 154 node_t d; 155 int l, r; 156 157 scanf("%d", &q); 158 while (q--) { 159 scanf("%d %d", &l, &r); 160 memset(visit, false, sizeof(visit)); 161 d = Query(l, r, 1, n, 1); 162 rep(i, 0, 9) { 163 if (d.st & (1<<i)) 164 visit[i] = true; 165 } 166 visit[9] = visit[0]; 167 visit[0] = (zn[r] - zn[l-1]) > 0; 168 int cnt = 5; 169 per(i, 0, 10) { 170 if (visit[i]) { 171 if (cnt == 5) 172 printf("%d", i); 173 else 174 printf(" %d", i); 175 if (--cnt == 0) 176 break; 177 } 178 } 179 180 while (cnt) { 181 printf(" -1"); 182 --cnt; 183 } 184 putchar('\n'); 185 } 186 } 187 188 int main() { 189 ios::sync_with_stdio(false); 190 #ifndef ONLINE_JUDGE 191 freopen("data.in", "r", stdin); 192 freopen("data.out", "w", stdout); 193 #endif 194 195 int t; 196 197 init(); 198 scanf("%d", &t); 199 rep(tt, 1, t+1) { 200 scanf("%d", &n); 201 rep(i, 1, n+1) { 202 scanf("%d", &a[i]); 203 zn[i] = zn[i-1] + (a[i] == 0); 204 a[i] %= 9; 205 } 206 printf("Case #%d:\n", tt); 207 solve(); 208 if (tt != t) 209 putchar('\n'); 210 } 211 212 #ifndef ONLINE_JUDGE 213 printf("time = %d.\n", (int)clock()); 214 #endif 215 216 return 0; 217 }
数据发生器。
1 from copy import deepcopy 2 from random import randint, shuffle 3 import shutil 4 import string 5 6 7 def GenDataIn(): 8 with open("data.in", "w") as fout: 9 t = 10 10 bound = 10**9 11 fout.write("%d\n" % (t)) 12 for tt in xrange(t): 13 n = randint(10, 20) 14 fout.write("%d\n" % (n)) 15 L = [] 16 for i in xrange(1, n): 17 x = randint(0, bound) 18 L.append(x) 19 L.append(0) 20 shuffle(L) 21 fout.write(" ".join(map(str, L)) + "\n") 22 q = (n+1)*n/2 23 fout.write("%d\n" % (q)) 24 for l in xrange(1, n+1): 25 for r in xrange(l, n+1): 26 fout.write("%d %d\n" % (l, r)) 27 28 29 def MovDataIn(): 30 desFileName = "F:\eclipse_prj\workspace\hdoj\data.in" 31 shutil.copyfile("data.in", desFileName) 32 33 34 if __name__ == "__main__": 35 GenDataIn() 36 MovDataIn()