注册 登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

Saffah's Blog

 
 
 

日志

 
 

CodeChef September Challenge 2014  

2014-09-10 09:42:16|  分类: CodeChef |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |
Chef and Left-Right
                             1
                        /           \
                  2                   4
                /   \                /       \
             3       5           7        9
            / \      /  \          /  \       /  \ 
           6 8 10 12   14 16 18 20 
有这样的一棵树(无穷的),给出一个lr序列,表示从根节点的一条路径,求终点的权值mod 1000000007。
序列长≤10^5,数据组数≤5。
Solution
找规律。如果当前节点x在奇数层,那么两个孩子分别是2x和2x+2;如果在偶数层,两个孩子分别是2x-1和2x+1。
  1. char s[100086];
  2. #define MOD 1000000007
  3.  
  4. int main(){
  5. int T; scanf("%d", &T);
  6. while(T--){
  7. scanf("%s", s);
  8. int n = strlen(s), dx = 0, c = 1;
  9. g(i, 0, n){
  10. if(s[i] == 'l') c = (c * 2 + dx) % MOD;
  11. else c = (c * 2 + 2 + dx) % MOD;
  12. dx = -1 - dx;
  13. }
  14. printf("%d\n", c);
  15. }
  16. return 0;
  17. }
Fun with Rotation
给一个序列,每次可以将序列顺时针或逆时针循环移动若干位,或询问某个下标的元素。
序列长度、询问个数≤10^5。
Solution
开个变量记录一下当前移动的位数,模拟就行了。
  1. int a[100086];
  2.  
  3. int main(){
  4. int n, m; scanf("%d%d", &n, &m);
  5. g(i, 0, n) scanf("%d", a + i);
  6. int dx = n - 1;
  7. while(m--){
  8. char op[4]; int d;
  9. scanf("%s%d", op, &d);
  10. if(op[0] == 'C') dx = (dx + d) % n;
  11. else if(op[0] == 'A') dx = (dx + n - d) % n;
  12. else printf("%d\n", a[(d + dx) % n]);
  13. }
  14. return 0;
  15. }
Chef and Rainbow Array - 2
定义一个数字串是“彩虹的”,当且仅当它的前a个元素是1,然后b个元素是2,然后c个元素是3,……,然后g个元素是7,然后f个元素是6,……,最后a个元素是1。给出N,问长度为N的彩虹数字串的个数mod 1000000007。
N≤10^6。
Solution
一个形如111..1122..2233..6677..7766..3322..2211的彩虹串必然是回文串,它的一半是111..1122..2233..6677..77,长度为(N+1)/2。答案就是长度为(N+1)/2的111..1122..2233..6677..77串的个数,答案就是C(length, 6)。
  1. #define MODLL 1000000007LL
  2. inline LL pow(LL x, int y){
  3. LL ans = 1;
  4. h(i, 30, 0){
  5. ans = ans * ans % MODLL;
  6. if(y & (1 << i)) ans = ans * x % MODLL;
  7. }
  8. return ans;
  9. }
  10. inline LL inv(LL x){
  11. return pow(x, MOD - 2);
  12. }
  13.  
  14. int main(){
  15. int n; scanf("%d", &n);
  16. LL a = (n + 1) / 2 - 1;
  17. printf("%lld\n", a * (a - 1LL) % MODLL * (a - 2LL) % MODLL * (a - 3LL) % MODLL * (a - 4LL) % MODLL * (a - 5LL) % MODLL * inv(720) % MODLL);
  18. return 0;
  19. }
Factorisation
给出不为1的正整数N,你需要找M个不为1的正整数A_1,A_2,...A_M,使得这M个数的乘积为N。得分是所有数据中M的平方的总和。
N≤10^1000,每个文件的数据组数≤100。
A类数据有10%,满足N≤10^18且均匀随机。
B类数据有15%,满足N≤10^18且是构造的。
C类数据有50%,N的长度是随机的,每一位也是随机的。
D类数据有25%,N的所有质因子不会超过10^18。
Solution
只会暴力高精除……
  1. char s[100086];
  2. std::vector<LL> ans;
  3. bool prime[1000086];
  4. int p[1000086], pn = 0;
  5. #define MAX 15500
  6. int _a[208], _b[208], *a = _a, *b = _b;
  7. int main(){
  8. // freopen("in", "r", stdin);
  9. int T; scanf("%d", &T);
  10. memset(prime, 1, sizeof(prime));
  11. f(i, 2, MAX) if(prime[i]){
  12. p[++pn] = i;
  13. for(int j = i * 2; j <= MAX; j += i) prime[j] = 0;
  14. }
  15. while(T--){
  16. scanf("%s", s);
  17. if(strlen(s) > 18){
  18. int l = strlen(s);
  19. memset(a, 0, sizeof(_a));
  20. int ci = 0, cj = 1;
  21. h(i, l - 1, 0){
  22. a[ci] += cj * (s[i] - '0');
  23. cj *= 10;
  24. if(cj == 100000){
  25. ++ci; cj = 1;
  26. }
  27. }
  28. ans.clear();
  29. f(j, 1, pn){
  30. int i = p[j];
  31. if(i > MAX) break;
  32. for(;;){
  33. int cj = 0;
  34. h(ci, 199, 0){
  35. b[ci] = a[ci] + cj;
  36. cj = b[ci] % i * 100000; b[ci] /= i;
  37. }
  38. if(cj) break;
  39. ans.push_back(i);
  40. std::swap(a, b);
  41. }
  42. }
  43. int mm = 199;
  44. while(!a[mm]) --mm;
  45. if(mm == 0 && a[0] == 1){
  46. printf("%d\n", ans.size());
  47. foreach(i, ans) printf("%lld\n", *i);
  48. }else{
  49. printf("%d\n", ans.size() + 1);
  50. foreach(i, ans) printf("%lld\n", *i);
  51. printf("%d", a[mm]);
  52. h(i, mm - 1, 0) printf("%05d", a[i]);
  53. printf("\n");
  54. }
  55. }else{
  56. LL a; sscanf(s, "%lld", &a);
  57. ans.clear();
  58. f(j, 1, pn){
  59. int i = p[j];
  60. if((LL) i * (LL) i > a) break;
  61. while(a % i == 0){
  62. ans.push_back(i); a /= i;
  63. }
  64. }
  65. if(a > 1) ans.push_back(a);
  66. printf("%d\n", ans.size());
  67. foreach(i, ans) printf("%lld\n", *i);
  68. }
  69. }
  70. return 0;
  71. }
Chef and sequence
给出一个长度为N整数序列,要求修改不超过K个元素(也必须改成整数),使得序列成为等差数列。(数据保证有解)
如果有多个方案,选择首项最小的;如果依然有多个,选择公差最小的。
2≤N≤10^5,0≤K≤min(10,N-2)。
Solution
做法是:每次随机选两个元素,检查能否构成整数等差数列和能否保证修改不超过K个元素。如果合法,更新答案。
这样做是对的,我们考虑两种情况:
N很小,那么因为最优解中总有至少2个元素不会被改动,我们几乎以1的概率尝试过这2个元素的组合。
N很大,那么因为最优解中总有至少N-2个元素不会被改动,我们几乎以1的概率尝试过这N-2个元素中任意两个元素的组合。
  1. int n, a[100086];
  2.  
  3. inline bool line(LL x1, LL y1, LL x2, LL y2, LL x3, LL y3){
  4. return (y2 - y1) * (x3 - x1) == (y3 - y1) * (x2 - x1);
  5. }
  6.  
  7. int main(){
  8. srand(time(0));
  9. int n, k; scanf("%d%d", &n, &k);
  10. f(i, 1, n) scanf("%d", a + i);
  11. LL a0 = 0x1f1f1f1f1f1f1f1fLL, d = 0x1f1f1f1f1f1f1f1fLL; int bs, bt;
  12. int T = 10000000 / n;
  13. while(T--){
  14. int s, t;
  15. do{
  16. s = rand() % n + 1;
  17. t = rand() % n + 1;
  18. }while(s == t);
  19. if((a[t] - a[s]) % (t - s)) continue;
  20. LL ca0 = ((LL) a[s] * t - (LL) a[t] * s + a[t] - a[s]) / (t - s), cd = (a[t] - a[s]) / (t - s);
  21. if(ca0 > a0 || (ca0 == a0 && cd > d)) continue;
  22. int ans = 0;
  23. f(i, 1, n) if(i != s && i != t && !line(s, a[s], t, a[t], i, a[i])) if((++ans) > k) break;
  24. if(ans <= k){
  25. a0 = ca0; d = cd; bs = s; bt = t;
  26. }
  27. }
  28. int s = bs, t = bt;
  29. f(i, 1, n) if(i == s || i == t || line(s, a[s], t, a[t], i, a[i])) printf("%d ", a[i]); else printf("%lld ", ((LL) a[s] * t - (LL) a[t] * s + (LL) i * (a[t] - a[s])) / (t - s));
  30. printf("\n");
  31. return 0;
  32. }
Flooring
给出N,求sigma_{1≤i≤N} (i^4 * floor(N/i))。答案对M取模输出。
N≤10^10,M≤10^5。
Solution
应该是裸题了吧。i不超过sqrt(N)的部分暴力,i超过sqrt(N)的时候,floor(N/i)的取值就不会超过sqrt(N)。
第二部分的暴力会用到sigma_{1≤i≤N} i^4的求和公式,大概怎么搞都可以。
  1. LL MOD;
  2. inline LL sum(LL x){
  3. return (((6LL * x + 15LL) % MOD * x + 10LL) % MOD * x % MOD * x + MOD - 1LL) % MOD * x % MOD;
  4. }
  5.  
  6. int main(){
  7. int T; scanf("%d", &T);
  8. while(T--){
  9. LL n; int m; scanf("%lld%d", &n, &m);
  10. MOD = m * 30;
  11. int til = sqrt(n);
  12. LL ans = 0;
  13. g(i, 1, til) (ans += (sum(n / i) + MOD - sum(n / (i + 1))) % MOD * i % MOD) %= MOD;
  14. til = n / til;
  15. f(i, 1, til) (ans += (LL) i * i % MOD * i % MOD * i % MOD * (n / i) % MOD * 30LL % MOD) %= MOD;
  16. printf("%lld\n", ans / 30);
  17. }
  18. return 0;
  19. }
Chef and Swaps
给出一个长度为N的序列A和M次询问,每次询问给出i和j,问:假如交换A_i和A_j,序列A的逆序对数。
N,M≤2*10^5。
Solution
先求逆序对,可以线段树搞。
注意询问的是“假如”,减去这两个位置原来的贡献再加上新的贡献就行了。算贡献可以偷懒把之前的线段树可持久化一下就行了= =……
  1. struct node{
  2. node *ls, *rs; int sum;
  3. inline node(){}
  4. } pool[10485760], *cp = pool;
  5. inline node *newnode(node *ls, node *rs){
  6. cp->ls = ls; cp->rs = rs; cp->sum = ls->sum + rs->sum; return cp++;
  7. }
  8. inline node *newnode(int sum){
  9. cp->ls = cp->rs = NULL; cp->sum = sum; return cp++;
  10. }
  11. inline node *build(int n){
  12. if(n == 1) return newnode(0); else return newnode(build((n + 1) >> 1), build(n >> 1));
  13. }
  14. inline node *inc(node *root, int l, int r, int x){
  15. if(l == r) return newnode(root->sum + 1);
  16. else{
  17. int m = (l + r) >> 1;
  18. if(x <= m) return newnode(inc(root->ls, l, m, x), root->rs);
  19. else return newnode(root->ls, inc(root->rs, m + 1, r, x));
  20. }
  21. }
  22. inline int query(node *root, int l, int r, int ll, int rr){
  23. int ans = 0;
  24. for(;;){
  25. if(l == ll && r == rr) return ans + root->sum;
  26. else{
  27. int m = (l + r) >> 1;
  28. if(rr <= m){
  29. root = root->ls; r = m;
  30. }else if(ll > m){
  31. root = root->rs; l = m + 1;
  32. }else{
  33. ans += query(root->ls, l, m, ll, m);
  34. root = root->rs; ll = l = m + 1;
  35. }
  36. }
  37. }
  38. }
  39. node *root[200086];
  40. int n, m, a[200086], b[200086], bn;
  41. inline int query(node *root, int ll, int rr){
  42. if(ll > rr) return 0; else return query(root, 1, bn, ll, rr);
  43. }
  44. int main(){
  45. read(n); read(m);
  46. f(i, 1, n) read(a[i]);
  47. memcpy(b, a, sizeof(b));
  48. std::sort(b + 1, b + (n + 1));
  49. bn = std::unique(b + 1, b + (n + 1)) - (b + 1);
  50. f(i, 1, n) a[i] = std::lower_bound(b + 1, b + (bn + 1), a[i]) - b;
  51. root[0] = build(bn);
  52. LL ans = 0;
  53. f(i, 1, n){
  54. root[i] = inc(root[i - 1], 1, bn, a[i]);
  55. ans += (LL) query(root[i], a[i] + 1, bn);
  56. }
  57. while(m--){
  58. int x, y; read(x); read(y);
  59. LL tmp = ans;
  60. if(a[x] < a[y]){
  61. tmp -= query(root[x - 1], a[x] + 1, a[y]);
  62. tmp += query(root[y], a[x], a[y] - 1);
  63. ++tmp;
  64. tmp += query(root[y - 1], a[x] + 1, a[y]);
  65. tmp -= query(root[x], a[x], a[y] - 1);
  66. }else if(a[y] < a[x]){
  67. tmp -= query(root[y - 1], a[y] + 1, a[x]);
  68. tmp += query(root[x], a[y], a[x] - 1);
  69. ++tmp;
  70. tmp += query(root[x - 1], a[y] + 1, a[x]);
  71. tmp -= query(root[y], a[y], a[x] - 1);
  72. }
  73. printf("%lld\n", tmp);
  74. }
  75. return 0;
  76. }
Sereja and Bubble Sort
对于一个序列A,f(A)表示用冒泡排序将它升序排列所需的交换次数。
现在给出一个长为n的序列(是1到n的某个排列),允许你进行不超过k次操作。每次可以交换某一对相邻的两个数,或将整个序列随机打乱。问在最优策略下,最终序列的f值的期望。
n≤100,数据组数≤100,k≤10^18。
Solution
首先f(A)就是逆序对= =……(跟上一题撞了?)
发现最优策略一定是:如果当前的f还行,就进行k次交换(每次都能使f减少1);如果当前的f太差了,就随机换一下,直到觉得f还行为止。
如何决定当前f的优劣呢?设best[i]表示:如果还剩i次交换,那么应该让≤best[i]的所有f都不再进行随机。
那么易得best[i]-i≤avg[i-1],其中avg[i]表示:如果当前序列是随机序列,并且还有i次交换机会,那么期望的最终序列的f值。
考虑如何求avg[i],我们考虑当前逆序对数j:对于不超过best[i]的j,应该不进行随机,超过best[i]的应该随机。那么avg[i]=sigma_{1≤j≤best[i]} P[n][j]*max(j-i,0) + sigma_{best[i]<j≤tot} P[n][j]*avg[i-1]。其中P[i][j]表示长度为i的随机序列,其逆序对数为j的概率,tot表示长度为n的序列的最大逆序对数。
P[i][j]容易处理得到:P[i][j]=sigma_{0≤k<i} P[i-1][j-k],用前缀和优化一下即可。
将avg的式子改写为:avg[i]=sigma{i<j≤best[i]} j*P[n][j] - i*sigma{i<j≤best[i]} P[j] + avg[k-1]*sigma{best[i]<j≤tot} P[j],发现除了上面的前缀和外,还需要一个j*P[n][j]的前缀和就可以做了。
最后比较f(A)和best[k],如果f(A)≤best[k]就输出max(f(A)-k,0),否则输出avg[k-1]。
  1. double dp[108][5120], sdp[108][5120], sdp2[108][5120];
  2. int a[108], best[5120]; double avg[5120];
  3.  
  4. int main(){
  5. memset(dp, 0, sizeof(dp));
  6. dp[1][0] = 1;
  7. f(j, 0, 5000) sdp[1][j] = 1;
  8. f(i, 2, 100) f(j, 0, 5000){
  9. dp[i][j] = sdp[i - 1][j];
  10. if(j >= i) dp[i][j] -= sdp[i - 1][j - i];
  11. dp[i][j] /= i;
  12. if(j){
  13. sdp[i][j] = sdp[i][j - 1] + dp[i][j];
  14. sdp2[i][j] = sdp2[i][j - 1] + j * dp[i][j];
  15. }else{
  16. sdp[i][j] = dp[i][j];
  17. sdp2[i][j] = 0;
  18. }
  19. }
  20. int T; scanf("%d", &T);
  21. while(T--){
  22. int n; long long k; scanf("%d%lld", &n, &k);
  23. f(i, 1, n) scanf("%d", a + i);
  24. int cans = 0;
  25. f(i, 1, n) f(j, i + 1, n) if(a[i] > a[j]) ++cans;
  26. if(cans <= k){
  27. printf("0\n"); continue;
  28. }else if(k == 0){
  29. printf("%d\n", cans); continue;
  30. }
  31. int MAX = n * (n - 1) / 2;
  32. avg[0] = MAX / 2.0;
  33. f(i, 1, MAX){
  34. best[i] = avg[i - 1] + i;
  35. if(best[i] > MAX) best[i] = MAX;
  36. avg[i] = sdp2[n][best[i]] - sdp2[n][i] - i * (sdp[n][best[i]] - sdp[n][i]) + avg[i - 1] * (sdp[n][MAX] - sdp[n][best[i]]);
  37. }
  38. if(cans <= best[k]) printf("%d\n", cans - k); else printf("%.10lf\n", avg[k - 1]);
  39. }
  40. return 0;
  41. }
Rectangle Query
Q次操作,每次可以在坐标平面上插入一个矩形,或是删除一个已插入的矩形,或是问某个矩形与多少个矩形有公共点。
Q≤10^5,坐标范围≤10^9,可以离线。
Solution
首先把坐标离散化成O(Q)的。
统计有公共点可能有点麻烦,不妨反过来统计与多少个矩形没有公共点。
考虑一个已知矩形A和询问矩形B,A与B没有公共点,当且仅当A完全在B的左边,完全在B的右边,完全在B的上边或完全在B的下边。
与B没有公共点的矩形个数=sigma_{dir∈"上下左右"}(完全在B的#{dir}方向的矩形个数) - sigma_{dir∈"左上 左下 右上 右下"}(完全在B的#{dir}方向的矩形个数)。
4种情况是旋转对称的,只需分别维护再相加。
现在只考虑一个方向,即求"完全在B左边的矩形个数 - 完全在B左下的矩形个数"。
CodeChef September Challenge 2014 - saffah - Saffahs Blog
只需要A的右上角在红色区域内部就行了。这样统计出的矩形个数就是"完全在B左边的矩形个数 - 完全在B左下的矩形个数"。
发现这只与A的右上角和B的左下角有关系。
现在问题变成了,坐标平面一堆点,每次可以给一个格子的数增加1(如果删除是减少1),或询问一个矩形区域的和。
可以离线分治扫描线或树套树……因为空间没压力,我写的是树状数组套动态开点线段树……
  1. int tot;
  2. struct node{
  3. node *ls, *rs; int sum;
  4. } pool[64827864], *nil, *cp;
  5. inline node *newnode(){
  6. cp->ls = cp->rs = nil; cp->sum = 0; return cp++;
  7. }
  8. inline void _chg(node *root, int x, int y, int l = 1, int r = tot){
  9. while(l < r){
  10. root->sum += y;
  11. int m = (l + r) >> 1;
  12. if(x <= m){
  13. if(root->ls == nil) root->ls = newnode();
  14. root = root->ls; r = m;
  15. }else{
  16. if(root->rs == nil) root->rs = newnode();
  17. root = root->rs; l = m + 1;
  18. }
  19. }
  20. root->sum += y;
  21. }
  22. inline int _sum(node *root, int ll, int rr, int l = 1, int r = tot){
  23. int ans = 0;
  24. for(;;){
  25. if(root == nil) return ans;
  26. if(l == ll && r == rr) return ans + root->sum;
  27. int m = (l + r) >> 1;
  28. if(rr <= m){
  29. root = root->ls; r = m;
  30. }else if(ll > m){
  31. root = root->rs; l = m + 1;
  32. }else{
  33. ans += _sum(root->ls, ll, m, l, m);
  34. root = root->rs; l = ll = m + 1;
  35. }
  36. }
  37. }
  38.  
  39. node *tree[200086];
  40. inline void chg(int x, int y, int z){
  41. for(; x <= tot; x += x & -x) _chg(tree[x], y, z);
  42. }
  43. inline int sum(int x, int y){
  44. int ans = 0;
  45. for(; x; x -= x & -x) ans += _sum(tree[x], y, tot);
  46. return ans;
  47. }
  48.  
  49. int xx[200086], yy[200086], xn = 0, yn = 0, ans[200086], rec[200086], rn = 0, rnb[200086];
  50. struct query{
  51. int x, y, x1, y1, x2, y2, z;
  52. //0 query 1 insert -1 delete
  53. } Q[100086];
  54.  
  55. inline void hhh(query &q, int x){
  56. if(q.z == 0){
  57. if(x == 0){
  58. q.x = q.x1; q.y = q.y1;
  59. }else if(x == 1){
  60. q.x = q.y1; q.y = tot + 1 - q.x2;
  61. }else if(x == 2){
  62. q.x = tot + 1 - q.x2; q.y = tot + 1 - q.y2;
  63. }else{
  64. q.x = tot + 1 - q.y2; q.y = q.x1;
  65. }
  66. }else{
  67. if(x == 0){
  68. q.x = q.x2; q.y = q.y2;
  69. }else if(x == 1){
  70. q.x = q.y2; q.y = tot + 1 - q.x1;
  71. }else if(x == 2){
  72. q.x = tot + 1 - q.x1; q.y = tot + 1 - q.y1;
  73. }else{
  74. q.x = tot + 1 - q.y1; q.y = q.x2;
  75. }
  76. }
  77. }
  78.  
  79. int main(){
  80. nil = new node;
  81. nil->ls = nil->rs = nil; nil->sum = 0;
  82. int q; scanf("%d", &q); tot = q * 2;
  83. rnb[0] = 0;
  84. f(i, 1, q){
  85. char buf[4]; scanf("%s", buf);
  86. if(buf[0] == 'D'){
  87. int tmp; scanf("%d", &tmp);
  88. Q[i] = Q[rec[tmp]]; Q[i].z = -1;
  89. }else{
  90. if(buf[0] == 'I'){
  91. Q[i].z = 1; rec[++rn] = i;
  92. }else Q[i].z = 0;
  93. scanf("%d%d%d%d", &Q[i].x1, &Q[i].y1, &Q[i].x2, &Q[i].y2);
  94. xx[xn++] = Q[i].x1; xx[xn++] = Q[i].x2;
  95. yy[yn++] = Q[i].y1; yy[yn++] = Q[i].y2;
  96. }
  97. rnb[i] = rnb[i - 1] + Q[i].z;
  98. }
  99. std::sort(xx, xx + xn); std::sort(yy, yy + yn);
  100. xn = std::unique(xx, xx + xn) - xx;
  101. yn = std::unique(yy, yy + yn) - yy;
  102. f(i, 1, q){
  103. Q[i].x1 = std::lower_bound(xx, xx + xn, Q[i].x1) - xx + 1;
  104. Q[i].y1 = std::lower_bound(yy, yy + yn, Q[i].y1) - yy + 1;
  105. Q[i].x2 = std::lower_bound(xx, xx + xn, Q[i].x2) - xx + 1;
  106. Q[i].y2 = std::lower_bound(yy, yy + yn, Q[i].y2) - yy + 1;
  107. }
  108. memset(ans, 0, sizeof(ans));
  109. f(xxx, 0, 3){
  110. cp = pool;
  111. f(i, 1, tot) tree[i] = newnode();
  112. f(i, 1, q){
  113. hhh(Q[i], xxx);
  114. if(Q[i].z == 0) ans[i] += sum(Q[i].x - 1, Q[i].y);
  115. else chg(Q[i].x, Q[i].y, Q[i].z);
  116. }
  117. // f(i, 1, q) if(Q[i].z == 0) printf("ans %d = %d\n", i, ans[i]);
  118. }
  119. f(i, 1, q) if(Q[i].z == 0) printf("%d\n", rnb[i] - ans[i]);
  120. return 0;
  121. }
Fibonacci Numbers on Tree
字数超了……见下一篇……
  评论这张
 
阅读(65)| 评论(0)
推荐 转载

历史上的今天

在LOFTER的更多文章

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2018