题目来源

[NOIP2016 提高组] 天天爱跑步 - 洛谷

题目考点
线段树   最近公共祖先,LCA树链剖分,树剖     Link-Cut Tree,LCT差分

题目描述

小c 同学认为跑步非常有趣,于是决定制作一款叫做《天天爱跑步》的游戏。《天天爱跑步》是一个养成类游戏,需要玩家每天按时上线,完成打卡任务。

这个游戏的地图可以看作一一棵包含 n 个结点和 n−1 条边的树,每条边连接两个结点,且任意两个结点存在一条路径互相可达。树上结点编号为从 1 到 n 的连续正整数。

现在有 m 个玩家,第 i 个玩家的起点为 si​,终点为 ti​。每天打卡任务开始时,所有玩家在第 0 秒同时从自己的起点出发,以每秒跑一条边的速度,不间断地沿着最短路径向着自己的终点跑去,跑到终点后该玩家就算完成了打卡任务。 (由于地图是一棵树,所以每个人的路径是唯一的)

小c 想知道游戏的活跃度,所以在每个结点上都放置了一个观察员。在结点 j 的观察员会选择在第 wj​ 秒观察玩家,一个玩家能被这个观察员观察到当且仅当该玩家在第 wj​ 秒也正好到达了结点 jj。小c 想知道每个观察员会观察到多少人?

注意:我们认为一个玩家到达自己的终点后该玩家就会结束游戏,他不能等待一 段时间后再被观察员观察到。 即对于把结点 j 作为终点的玩家:若他在第 wj​ 秒前到达终点,则在结点 j 的观察员不能观察到该玩家;若他正好在第 wj​ 秒到达终点,则在结点 j 的观察员可以观察到这个玩家。

输入格式

第一行有两个整数 n 和 m。其中 n 代表树的结点数量, 同时也是观察员的数量, m 代表玩家的数量。

接下来 n−1 行每行两个整数 u 和 v,表示结点 u 到结点 v 有一条边。

接下来一行 n 个整数,其中第 j 个整数为 wj​ , 表示结点 j 出现观察员的时间。

接下来 m 行,每行两个整数 si​,和 ti​,表示一个玩家的起点和终点。

对于所有的数据,保证 1≤si​,ti​≤n,0≤wj​≤n。

输出格式

输出 1 行 n 个整数,第 j 个整数表示结点 j 的观察员可以观察到多少人。

输入输出样例

输入 #1

6 3
2 3
1 2
1 4
4 5
4 6
0 2 5 1 2 3
1 5
1 3
2 6 

输出 #1

2 0 0 1 1 1 

输入 #2

5 3
1 2
2 3
2 4
1 5
0 1 0 3 0
3 1
1 4
5 5 

输出 #2

1 2 1 0 1 

说明/提示

【样例1说明】

对于 11 号点,w_i=0wi​=0,故只有起点为 11 号点的玩家才会被观察到,所以玩家 11 和玩家 22 被观察到,共有 22 人被观察到。

对于 22 号点,没有玩家在第 22 秒时在此结点,共 00 人被观察到。

对于 33 号点,没有玩家在第 55 秒时在此结点,共 00 人被观察到。

对于 44 号点,玩家 11 被观察到,共 11 人被观察到。

对于 55 号点,玩家 11 被观察到,共 11 人被观察到。

对于 66 号点,玩家 33 被观察到,共 11 人被观察到。

【子任务】

每个测试点的数据规模及特点如下表所示。
提示: 数据范围的个位上的数字可以帮助判断是哪一种数据类型。

【提示】

如果你的程序需要用到较大的栈空间 (这通常意味着需要较深层数的递归), 请务必仔细阅读选手目录下的文本文档 running/stack.txt, 以了解在最终评测时栈空间的限制与在当前工作环境下调整栈空间限制的方法。

在最终评测时,调用栈占用的空间大小不会有单独的限制,但在我们的工作环境中默认会有 1 \text{MiB}1MiB 的限制。 这可能会引起函数调用层数较多时, 程序发生栈溢出崩溃。

我们可以使用一些方法修改调用栈的大小限制。 例如, 在终端中输入下列命令 ulimit -s 1048576

此命令的意义是,将调用栈的大小限制修改为 1 \text{GiB}1GiB。

例如,在选手目录建立如下 sample.cpp 或 sample.pas

将上述源代码编译为可执行文件 sample 后,可以在终端中运行如下命令运行该程序

./sample

如果在没有使用命令“ ulimit -s 1048576”的情况下运行该程序, sample 会因为栈溢出而崩溃; 如果使用了上述命令后运行该程序,该程序则不会崩溃。

特别地, 当你打开多个终端时, 它们并不会共享该命令, 你需要分别对它们运行该命令。

请注意, 调用栈占用的空间会计入总空间占用中, 和程序其他部分占用的内存共同受到内存限制。

题解

首先声明这不是一篇算法独特的题解,仍然是“LCA+桶+树上差分”,但这篇题解是为了让很多很多看了很多题解仍然看不懂的朋友们看懂的,其中就包括我,我也在努力地把解题的“思维过程”呈现出来,希望能帮助到别人。实在是佩服那些考场AC的大牛,再次向你们献上敬意!

原文链接(https://www.cnblogs.com/lfyzoi/p/10221884.html)

1. 第一步

  • 首先可以初步判断这个题肯定要计算LCA,方法有倍增/Tarjan-DFS,我们就写个简单的倍增吧,使用链式前向星存储边。
  • 选择1号结点开始dfs,别的结点也可以
  • dfs过程中计算fa[][]数组(fa[x][i]表示 xx 结点的 2^i2i 代祖先是谁)和deep[]数组(deep[x]表示结点 xx 在树中的深度)
​
#include<bits/stdc++.h>
using namespace std;
const int SIZE=300000;
int n, m, tot, h[SIZE], deep[SIZE], fa[SIZE][20], w[SIZE];      //w[i]表示i结点出现观察员的时间
struct edge
{int to, next;
}E[SIZE*2], e1[SIZE*2], e2[SIZE*2];                             //边集数组e1,e2留待备用void add(int x, int y)                                          //加边函数
{E[++tot].to=y;E[tot].next=h[x];h[x]=tot;
}void dfs1(int x)                                                //dfs的过程中完成“建树”,预处理fa[][]数组, 计算deep[]数组
{for(int i=1; (1<<i)<=deep[x]; i++)fa[x][i]=fa[fa[x][i-1]][i-1];                           //x的2^i代祖宗就是x的2^{i-1}代祖宗的2^{i-1}代祖宗for(int i=h[x]; i; i=E[i].next){int y=E[i].to;if(y==fa[x][0])  continue;                               //如果y是父结点,跳过fa[y][0]=x;deep[y]=deep[x]+1;dfs1(y);}
}int get_lca(int x, int y)                                      //计算x和y的最近公共祖先
{if(x==y) return x;                                         //没有这一行,遇到 lca(x, x) 这样的询问时会挂掉if(deep[x]<deep[y]) swap(x, y);                            //保持x的深度大于y的深度int t=log(deep[x]-deep[y])/log(2);for(int i=t; i>=0; i--)                                    //x向上跳到和y同样的深度{if(deep[fa[x][i]]>=deep[y])x=fa[x][i];if(x==y)return x;}t=log(deep[x])/log(2);for(int i=t; i>=0; i--)                                    //x和y一起向上跳{if(fa[x][i]!=fa[y][i])x=fa[x][i], y=fa[y][i];}return fa[x][0];
}int main()                                                     //先把主函数写上一部分
{scanf("%d%d", &n, &m);for(int i=1; i<n; i++){int u, v;scanf("%d%d", &u, &v);add(u, v);add(v, u);}deep[1]=1;fa[1][0]=1;dfs1(1);for(int i=1; i<=n; i++) scanf("%d", &w[i]);/未完待续////return 0;
}​

2. 第二步

大概分析一下,m个玩家对应m条路径,有了起点和终点的 lca 后,如果我们模拟这个过程:

直觉

  • 从起点 S_iSi​ 跑到 LCALCA 在树长得很匀称的情况下为 O(lgn)O(lgn)
  • 从起点 LCALCA 跑到 T_iTi​ 在树长得很匀称的情况下为 O(lgn)O(lgn)
  • 因此,模拟一个玩家的跑步过程为 O(lgn)O(lgn),m个玩家为 O(mlgn)O(mlgn)
  • 理想情况下是可行的,但现实就是不理想
  • 题目清楚告诉你,树会退化成一条链,因此模拟一个过程变成 O(n)O(n),总的就是。。。O(mn)O(mn),必挂无疑
  • 此法不是正解!

尝试

  • 我们能不能改变模拟跑步的过程,从 O(n)O(n) 优化到 O(lgn)O(lgn) 呢?思前想后不可能,有 nn 个观察员矗在那里,你可以对哪个视而不见?
  • 路已走到尽头

转换

  • 这时候需要放大招,转换思想!或许解决问题的思路压根就不是一个玩家一个玩家模拟,而是整体处理呢?
  • 也就是说,我们不枚举每个运动员而是枚举每个观察员i,看看哪些结点会为这个观察员i做贡献(刚好在w_iwi​秒跑到他这儿)。
  • 枚举观察员的过程就是DFS整颗树的过程,我们可以在 O(n)O(n) 内搞定!
  • 对于观察员i,哪些人会为他做贡献呢?

深入分析

  • 对于结点 PP, 如果他位于一条起点、终点分别为 s_isi​, t_iti​ 的跑步路径上,如何判断这名选手会不会为 PP 作贡献呢?
  • 分情况考虑
  • 如果 PP 是在从 s_isi​ 到 LCALCA 的路上,如下图:

  • 我们可以得出结论:当起点 s_isi​ 满足 deep[s_i]=w[P]+deep[P]deep[si​]=w[P]+deep[P]时,起点 s_isi​会为 PP 观察员做一个贡献(运动员从s_isi​出发,可以被PP处的观察员在w[P]w[P]秒看到)

  • 如果 PP 是在从 LCALCA 到 t_iti​ 的路上,如下图:

  • 定义 dist[s_i, t_i]dist[si​,ti​]为从 s_isi​出发到t_iti​的路径长度,如果运动员从s_isi​出发,可以被PP处的观察员在w[P]w[P]秒观察到,可以由上图得出以下式子:
  • dist[s_i, t_i]-w[P]=deep[t_i]-deep[P]dist[si​,ti​]−w[P]=deep[ti​]−deep[P],移项后得到:
  • dist[s_i, t_i]-deep[t_i]=w[P]-deep[P]dist[si​,ti​]−deep[ti​]=w[P]−deep[P]
  • 我们可以得出结论:当终点 t_iti​ 满足 dist[s_i, t_i]-deep[t_i]=w[P]-deep[P]dist[si​,ti​]−deep[ti​]=w[P]−deep[P]时,终点 t_iti​会为 PP 观察员做一个贡献
  • 做一个重要的总结:上行过程中,满足条件的起点可以做贡献,下行过程中,满足条件的终点可以做贡献,但无论是哪一种情形,能对 PP 做贡献的起点或终点一定都在以PP为根的子树上,这使得可以在DFS回溯的过程中处理以任意节点为根的子树。

3. 第三步

如何统计子树贡献

  • 递归以PP为根的子树时,可以统计出其子树中所有的起点和终点对它的贡献
  • 这里又需要转换
  • 子树中有的起点和终点对PP产生了贡献,有些不对其产生贡献但对PP以外的结点产生了贡献
  • 所以我们不能枚举每个点(子树根),找子树中哪些点对其产生贡献,这样复杂度就上去了
  • 而是对于树上的任何一个起点和终点,把其产生的贡献放在桶里面,回溯到子树根的时候再到桶里面查询结果
  • 有人产生疑问了,也是很多人看不懂这里桶用法的地方,疑问如图:

  • cc点产生贡献放在桶的deep[c]deep[c]位置,计算bb点获得的贡献时当然是从bucket1[deep[b]+w[b]]bucket1[deep[b]+w[b]]位置获取,于是得到1个贡献,你发现aa结点也是用的同一个桶,这个还好,因为cc确实给他做了贡献,可是ee点呢?他是不应该获得贡献的!既然我会给和我无关的结点做贡献,那么其它无关的结点难免也会给我做贡献!
  • 问题总结一下,对于一个点PP来说,究竟哪些点在桶里面产生的贡献才是有效的。
  • 答案是:以PP为根递归整颗子树过程中在桶内产生的差值才是有效的

还要考虑一种情况

  • 先看图:

  • 看懂了吗?对于以PP为根的内部路径(不经过PP),这条路径的起点和终点产生的贡献是不应该属于PP的
  • 所以dfs过程中,在统计当前结点作为起点和终点所产生的贡献后,继而计算出当前结点作为“根”上的差值后,在回溯过程中,一定要减去以当前结点为LCALCA的起点、终点在桶里产生的贡献,这部分贡献在离开这个子树后就没有意义了。

代码说明

  • e1,tot1,h1,add1是使用链式前向星的方法存储每个结点作为终点对应的路径集合
  • e2,tot2,h2,add2是使用链式前向星的方法存储每个结点作为LCA对应的路径集合
  • b1,b2是两组桶,分别用于上行阶段下行阶段的贡献统计
  • js[SIZE]用于统计以每个结点作为起点的路径条数
  • dist[SIZE], s[SIZE], t[SIZE]用于统计m条路径对应的长度,起点和终点信息
  • ans[SIZE]存储最后输出的答案,是每个结点观察员看到的人数
​
int tot1, tot2, h1[SIZE], h2[SIZE];
void add1(int x, int y)
{e1[++tot1].to=y;e1[tot1].next=h1[x];h1[x]=tot1;
}void add2(int x, int y)
{e2[++tot2].to=y;e2[tot2].next=h2[x];h2[x]=tot2;
}int b1[SIZE*2], b2[SIZE*2], js[SIZE], dist[SIZE], s[SIZE], t[SIZE], ans[SIZE];void dfs2(int x)
{int t1=b1[w[x]+deep[x]], t2=b2[w[x]-deep[x]+SIZE];      //递归前先读桶里的数值,t1是上行桶里的值,t2是下行桶的值for(int i=h[x]; i; i=E[i].next)                         //递归子树{int y=E[i].to;if(y==fa[x][0]) continue;dfs2(y);}b1[deep[x]]+=js[x];                                     //上行过程中,当前点作为路径起点产生贡献,入桶for(int i=h1[x]; i; i=e1[i].next)                       //下行过程中,当前点作为路径终点产生贡献,入桶{int y=e1[i].to;b2[dist[y]-deep[t[y]]+SIZE]++;}ans[x]+=b1[w[x]+deep[x]]-t1+b2[w[x]-deep[x]+SIZE]-t2;   //计算上、下行桶内差值,累加到ans[x]里面for(int i=h2[x]; i; i=e2[i].next)                       //回溯前清除以此结点为LCA的起点和终点在桶内产生的贡献,它们已经无效了{int y=e2[i].to;b1[deep[s[y]]]--;                                   //清除起点产生的贡献b2[dist[y]-deep[t[y]]+SIZE]--;                      //清除终点产生的贡献}
}int main()
{
重复部分跳过
文末提供完整代码for(int i=1; i<=m; i++)                                 //读入m条询问{scanf("%d%d", &s[i], &t[i]);int lca=get_lca(s[i], t[i]);                        //求LCAdist[i]=deep[s[i]]+deep[t[i]]-2*deep[lca]];         //计算路径长度js[s[i]]++;                                         //统计以s[i]为起点路径的条数,便于统计上行过程中该结点产生的贡献add1(t[i], i);                                      //第i条路径加入到以t[i]为终点的路径集合中add2(lca, i);                                       //把每条路径归到对应的LCA集合中if(deep[lca]+w[lca]==deep[s[i]]) ans[lca]--;        //见下面的解释}dfs2(1);                                                //dfs吧!for(int i=1; i<=n; i++) printf("%d ", ans[i]); return 0;
}​

一些重要补充

  • 上述代码中有一行未加解释if(deep[lca]+w[lca]==deep[s[i]]) ans[lca]--;
  • 考虑路径是这样的,如图:

  • 这个图可能不太好懂,意思是:

  • 如果路径起点或终点刚好为LCA且LCA处是可观察到运动员的,那么我们在上行统计过程中和下行统计过程中都会对该LCA产生贡献,这样就重复计数一次!

  • 好在这种情况很容易发现,我们提前预测到,对相应的结点进行ans[x]--即可。

  • 此外,在使用第二个桶时,下标是w[x]-deep[x]会成为负数,所以使用第二个桶时,下标统一+SIZE,向右平移一段区间,防止下溢。

4. 结束

我不知道自己说清楚没有,但愿大家不要拍砖头!下面是完整代码

​
#include<bits/stdc++.h>
using namespace std;
const int SIZE=300000;
int n, m, tot, h[SIZE], deep[SIZE], fa[SIZE][20], w[SIZE];
struct edge
{int to, next;
}E[SIZE*2], e1[SIZE*2], e2[SIZE*2];void add(int x, int y)
{E[++tot].to=y;E[tot].next=h[x];h[x]=tot;
}int tot1, tot2, h1[SIZE], h2[SIZE];
void add1(int x, int y)
{e1[++tot1].to=y;e1[tot1].next=h1[x];h1[x]=tot1;
}
void add2(int x, int y)
{e2[++tot2].to=y;e2[tot2].next=h2[x];h2[x]=tot2;
}void dfs1(int x)
{for(int i=1; (1<<i)<=deep[x]; i++)fa[x][i]=fa[fa[x][i-1]][i-1];for(int i=h[x]; i; i=E[i].next){int y=E[i].to;if(y==fa[x][0])    continue;fa[y][0]=x;deep[y]=deep[x]+1;dfs1(y);}
}int get_lca(int x, int y)
{if(x==y) return x;if(deep[x]<deep[y]) swap(x, y);int t=log(deep[x]-deep[y])/log(2);for(int i=t; i>=0; i--){if(deep[fa[x][i]]>=deep[y])x=fa[x][i];if(x==y)return x;}t=log(deep[x])/log(2);for(int i=t; i>=0; i--){if(fa[x][i]!=fa[y][i])x=fa[x][i], y=fa[y][i];}return fa[x][0];
}int b1[SIZE*2], b2[SIZE*2], js[SIZE], dist[SIZE], s[SIZE], t[SIZE], l[SIZE], ans[SIZE];
void dfs2(int x)
{int t1=b1[w[x]+deep[x]], t2=b2[w[x]-deep[x]+SIZE];for(int i=h[x]; i; i=E[i].next){int y=E[i].to;if(y==fa[x][0]) continue;dfs2(y);}b1[deep[x]]+=js[x];for(int i=h1[x]; i; i=e1[i].next){int y=e1[i].to;b2[dist[y]-deep[t[y]]+SIZE]++;}ans[x]+=b1[w[x]+deep[x]]-t1+b2[w[x]-deep[x]+SIZE]-t2;for(int i=h2[x]; i; i=e2[i].next){int y=e2[i].to;b1[deep[s[y]]]--;b2[dist[y]-deep[t[y]]+SIZE]--;}
}int main()
{scanf("%d%d", &n, &m);for(int i=1; i<n; i++){int u, v;scanf("%d%d", &u, &v);add(u, v);add(v, u);}deep[1]=1;fa[1][0]=1;dfs1(1);for(int i=1; i<=n; i++) scanf("%d", &w[i]);for(int i=1; i<=m; i++){scanf("%d%d", &s[i], &t[i]);int lca=get_lca(s[i], t[i]);dist[i]=deep[s[i]]+deep[t[i]]-2*deep[lca];js[s[i]]++;add1(t[i], i);add2(lca, i);if(deep[lca]+w[lca]==deep[s[i]]) ans[lca]--;}dfs2(1);for(int i=1; i<=n; i++) printf("%d ", ans[i]);return 0;
}​

P1600 [NOIP2016 提高组] 天天爱跑步相关推荐

  1. [NOIP2016 提高组] 天天爱跑步(树上差分)

    如果没有时间的限制,这题就是对每个点iii,求经过iii的路径数,用树上差分解决即可: 枚举路径x→y{x\to y\{x→y{ a[x]+=1;a[y]+=1;a[x]+=1;a[y]+=1;a[x ...

  2. NOIP2016提高组 天天爱跑步

    (树上差分 + \(LCA\)) \(O(Mlog_2N)\) 调了两个小时,最后发现把\(lca\)里的\(y\)写成\(x\)了,当场去世. 首先下几个定义: \(dis[x]\) 为\(x\)到 ...

  3. 【NOIP2016提高组】天天爱跑步

    题目背景 NOIP2016 提高组 Day1 T2 题目描述 小 C 同学认为跑步非常有趣,于是决定制作一款叫做<天天爱跑步>的游戏.<天天爱跑步>是一个养成类游戏,需要玩家每 ...

  4. P1850 [NOIP2016 提高组] 换教室

    P1850 [NOIP2016 提高组] 换教室 题意: 有2n个课安排在n个时间段上,每个时间段上都有两个一样的课同时在不同地方上,起初牛牛被所有课都被安排在Ci上课,另一节课在Di上课.牛牛现在想 ...

  5. [NOIP2016 提高组] 愤怒的小鸟

    [NOIP2016 提高组] 愤怒的小鸟 题意: 有n只猪,给出猪的坐标(xi,yi),问最少用几个形如 y=ax^2+bx 的曲线可以保证所有猪在曲线上,满足a<0,a,b为实数 n<= ...

  6. #185. [NOIP2016 提高组] 蚯蚓题解

    #185. [NOIP2016 提高组] 蚯蚓题解 题目描述 本题中,我们将用符号 ⌊c⌋\lfloor c \rfloor⌊c⌋ 表示对 ccc 向下取整,例如:⌊3.0⌋=⌊3.1⌋=⌊3.9⌋= ...

  7. NOIP2016提高组 第一天第二题 天天爱跑步running 题解

    题目描述 小c同学认为跑步非常有趣,于是决定制作一款叫做<天天爱跑步>的游戏.«天天爱跑步»是一个养成类游戏,需要玩家每天按时上线,完成打卡任务. 这个游戏的地图可以看作一一棵包含 个结点 ...

  8. NOIP2016 提高组 解题报告

    说明:由于我能力的限制,文章中的做法不一定是最优秀的算法,但官方数据全部测试通过,使用的全部知识全部是NOIP提高组的知识,请组织放心查看. 感谢 GoodQt 的指导与帮助 DAY1 T1 玩具谜题 ...

  9. NOIP2016·洛谷·天天爱跑步

    初见安~这里是传送门:洛谷P1600 题目描述 小c同学认为跑步非常有趣,于是决定制作一款叫做<天天爱跑步>的游戏.<天天爱跑步>是一个养成类游戏,需要玩家每天按时上线,完成打 ...

  10. [FROM LUOGU]P1600 【NOIP2016DAY1T2】天天爱跑步

    P1600 天天爱跑步 题面 小c同学认为跑步非常有趣,于是决定制作一款叫做<天天爱跑步>的游戏.<天天爱跑步>是一个养成类游戏,需要玩家每天按时上线,完成打卡任务. 这个游戏 ...

最新文章

  1. servlet response 中文乱码
  2. 斯坦福SAIL负责人Christopher Manning:语言理解是人机灵魂的桥梁
  3. 010-ThreadGroup线程组
  4. maven配置开源中国镜像
  5. java技术入门培训_入门java怎么自学?推荐谁的课程?
  6. NAB 2019见闻:CAE视频编码与QoE
  7. webrtc java api_WEBRTC--简单入门实例
  8. “融合、智能、绿色”施耐德电气线上工博以全生命周期解决方案助推数字化
  9. mysql 短信发送情况检查
  10. sourcetree 忽略目录_SourceTree安装与使用方法
  11. C++之获取配置文件值
  12. C++:建立一个被称为sroot()的函数,返回其参数的二次方根。重载sroot()3次,让它返回整数、长整数与双精度的二次方根
  13. android发现u盘自动安装apk,安卓自动识别U盘中APK文件并进行安装操作
  14. FreeRTOS学习笔记——FreeRTOS 时间管理
  15. 使用Layer弹窗时遇到Layer.Close()后dom元素延迟性销毁的问题 @Gyb
  16. 《Python基础知识-4判断和循环语句》
  17. 计算机教案三维目标,“三维目标”的三个问题 教学设计三维目标模板
  18. 全志A10/A20 nand flash系统开发
  19. CAD一键删除所有标注
  20. sap服务器文件上传,服务器上传数据sap

热门文章

  1. PageAdmin CMS建站系统的可视化编辑体验
  2. 拖库 洗库 撞库的概念
  3. 管理员后台爆破扫描器-WebCrack
  4. 网站优化众说纷纭 往左走还是往右走?
  5. ABC互联 shopex网店主机 试用
  6. 网维服务器无盘系统,网咖无盘系统网络和系统原理科普
  7. 移动端微博 php源码,jQuery仿手机新浪微博聊天界面
  8. 最拼命最努力的时候(转)
  9. 实时的含时密度泛函理论(rt-TDDFT)的算法进展及在超快动力学中的应用
  10. StretchDIBits速度测试(COLORONCOLOR)