UVa 12627 Erratic Expansion - 分治
因为不好复制题目,就出给出链接吧:
Vjudge传送门[here]
UVa传送门[here]
请仔细看原题上的那幅图,你会发现,在时间t(t > 0),当前的气球构成的一幅图,它是由三个时间为(t - 1)的图再加上一块全是蓝色的一块构成。所以可以想到递归求解。对于上半部分的行求前一时刻对应几行的红球数乘2,下面的减去2t - 1然后递归前一幅图求解。
但是这样最坏的时间复杂度为O(2k-1),仍然会TLE,那么得另寻出路。如果求在时刻t整个一幅图的红球个数,那么可以直接算出来,个数为3k。
因此在递归的过程中特判一下是不是求整个图的红球个数,可以把时间复杂度将为?O(log2n)
Code
1 /** 2 * UVa 3 * Problem#12627 4 * Accepted 5 * Time:0ms 6 */ 7 #include<iostream> 8 #include<cstdio> 9 #include<cctype> 10 #include<ctime> 11 #include<cstring> 12 #include<cstdlib> 13 #include<fstream> 14 #include<sstream> 15 #include<algorithm> 16 #include<map> 17 #include<set> 18 #include<stack> 19 #include<queue> 20 #include<vector> 21 #include<stack> 22 #ifndef WIN32 23 #define AUTO "%lld" 24 #else 25 #define AUTO "%I64d" 26 #endif 27 using namespace std; 28 typedef bool boolean; 29 #define inf 0xfffffff 30 #define smin(a, b) a = min(a, b) 31 #define smax(a, b) a = max(a, b) 32 template<typename T> 33 inline void readInteger(T& u){ 34 char x; 35 int aFlag = 1; 36 while(!isdigit((x = getchar())) && x != '-'); 37 if(x == '-'){ 38 x = getchar(); 39 aFlag = -1; 40 } 41 for(u = x - '0'; isdigit((x = getchar())); u = (u << 1) + (u << 3) + x - '0'); 42 ungetc(x, stdin); 43 u *= aFlag; 44 } 45 46 int T; 47 int n, a, b; 48 49 template<typename T> 50 T pow(T a, int pos) { 51 if(pos == 0) return 1; 52 if(pos == 1) return a; 53 T temp = pow(a, pos / 2); 54 if(pos & 1) return temp * temp * a; 55 return temp * temp; 56 } 57 58 inline void init() { 59 readInteger(n); 60 readInteger(a); 61 readInteger(b); 62 } 63 64 long long dfs(int dep, int top, int bottom) { 65 if(dep == 0) return 1; 66 if(top == 1 && bottom == (1 << dep)) return pow((long long)3, dep); 67 int mid = 1 << (dep - 1); 68 if(bottom <= mid) return 2 * dfs(dep - 1, top, bottom); 69 if(top > mid) return dfs(dep - 1, top - mid, bottom - mid); 70 return 2 * dfs(dep - 1, top, mid) + dfs(dep - 1, 1, bottom - mid); 71 } 72 73 inline void solve() { 74 long long res = dfs(n, a, b); 75 printf(AUTO"\n", res); 76 } 77 78 int main() { 79 readInteger(T); 80 for(int kase = 1; kase <= T; kase++) { 81 init(); 82 printf("Case %d: ", kase); 83 solve(); 84 } 85 return 0; 86 }