利用树的dfs序解决问题:

就是dfs的时候记录每个节点的进入时间和离开时间,这样一个完整的区间就是一颗完整的树,就转化成了区间维护的问题。

比如hdu3887 本质上是一个求子树和的问题

 #include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>
#include <iostream>
#include <stack>
//#pragma comment(linker,"/STACK:1024000000,1024000000")
using namespace std;
#define MAXN (200000+10)
#define lowbit(i) (i&(-i))
int n,m;
struct BIT{
int t[MAXN];
BIT(){memset(t,,sizeof(t));}
void init(){memset(t,,sizeof(t));}
int _query(int a){
int ans=;
for (int i=a;i>=;i-=lowbit(i)) ans+=t[i];
return ans;
}
void modify(int a,int x){
for (int i=a;i<=n;i+=lowbit(i)) t[i]+=x;
} int query(int a,int b){
return _query(b)-_query(a-);
}
}T;
int timemark;
int intime[MAXN],outime[MAXN];
int data[MAXN];
int f[MAXN];
int head[MAXN],next[MAXN],e[MAXN],countside;
void buildside(int a,int b){
e[countside]=b;
next[countside]=head[a];
head[a]=countside++;
}
/*
void dfs(int x,int fa){
intime[x]=timemark++;
for (int i=head[x];i>0;i=next[i]){
if (e[i]!=fa){
dfs(e[i],x);
}
}
outime[x]=timemark++;
}
*/ stack<int> s;
bool instack[MAXN];
void dfs(int root){
memset(instack,false,sizeof instack);
s.push(root);
intime[root]=timemark++;
instack[root]=true;
while (!s.empty()){
bool loop=false;
int now=s.top();
for (int i=head[now];i>;i=next[i]){
if (!instack[e[i]]){
s.push(e[i]);
instack[e[i]]=true;
intime[e[i]]=timemark++;
loop=true;
break;
}
}
if (loop) continue;
s.pop();
outime[now]=timemark++;
}
} int main (int argc, char *argv[])
{
int p;
int a,b;
char cmd[]; while (){
scanf("%d%d",&n,&p); if (n== && p==) break; memset(head,,sizeof head);
memset(next,,sizeof next);
memset(e,,sizeof e); countside=;
for (int i=;i<=n-;i++){
scanf("%d%d",&a,&b);
buildside(a,b);
buildside(b,a);
} timemark=;
dfs(p); /*for (int i=1;i<=n;i++) cout<<intime[i]<<" "<<outime[i]<<endl;*/ int N=n;
n=n*;
T.init();
for (int i=;i<=n;i++){
data[i]=;
T.modify(i,);
} for (int i=N;i>=;i--){
f[i]=(T.query(intime[i],outime[i])-)/;
T.modify(intime[i],-);
T.modify(outime[i],-);
} for (int i=;i<=N-;i++) printf("%d ",f[i]);
printf("%d\n",f[N]);
}
return ;
}

直接dfs爆栈了,所以我写了一个手工栈。结果后来发现这样就行了QAQ

 #pragma comment(linker,"/STACK:100000000,100000000")

WTF。。。涨姿势了

再就是对于那种复杂的序列操作问题,比如文本编辑器,我发现了C++ 里还有rope这个东西。当然这不是标准STL的,这是SGI STL的一部分。但是如果比赛的时候能用就爽了。。。不管怎么说先记录一下,平时也是蛮实用的。

rope就是一个能支持各种操作的序列,crope就是rope的字符串版本。rope自带各种炫酷的功能,时间各种logn,就连空间也超小。据说内部实现的是一个可持久化的平衡数并且加上共享节点。Orz

NOI 的那道文本编辑器

 #include <iostream>
#include <cstring>
#include <cstdlib>
#include <cstdio>
#include <ext/rope>
using namespace std;
using namespace __gnu_cxx;
crope List;
int n,now,k;
char s[];
int main()
{
char cmd[];
int i;
for (scanf("%d",&n);n--;)
{
scanf("%s",cmd);
if (cmd[]=='M') scanf("%d",&now);
else if (cmd[]=='I')
{
scanf("%d%*c",&k);
for (i=;i<k;i++) do
{
scanf("%c",&s[i]);
}while(s[i]=='\n');
s[k]=;
List.insert(now,s);
}
else if (cmd[]=='D')
{
scanf("%d",&k);
List.erase(now,k);
}
else if (cmd[]=='G')
{
scanf("%d",&k);
List.copy(now,k,s);
s[k]=;
puts(s);
}
else if (cmd[]=='P') now--;
else now++;
}
return ;
}

树的dfs序 && 系统栈 && c++ rope的更多相关文章

  1. [2]树的DFS序

    定义: 树的DFS序就是在对树进行DFS的时候,对树的节点进行重新编号:DFS序有一个很强的性质: 一颗子树的所有节点在DFS序内是连续的一段, 利用这个性质我们可以解决很多问题. 代码: void ...

  2. CF877E Danil and a Part-time Job 线段树维护dfs序

    \(\color{#0066ff}{题目描述}\) 有一棵 n 个点的树,根结点为 1 号点,每个点的权值都是 1 或 0 共有 m 次操作,操作分为两种 get 询问一个点 x 的子树里有多少个 1 ...

  3. HDU4117 GRE WORDS(AC自动机+线段树维护fail树的dfs序)

    Recently George is preparing for the Graduate Record Examinations (GRE for short). Obviously the mos ...

  4. 【BZOJ2286】消耗战(虚树,DFS序,树形DP)

    题意:一棵N个点的树上有若干个关键点,每条边有一个边权,现在要将这些关键点到1的路径全部切断,切断一条边的代价就是边权. 共有M组询问,每组询问有k[i]个关键点,对于每组询问求出完成任务的最小代价. ...

  5. 【BZOJ3611】大工程(虚树,DFS序,树形DP)

    题意:有一棵树,树有边权,有若干次询问,给出一些点,求: 1.这些点互相之间的距离之和 2.点对距离中的最大和最小值 n<=1000000 q<=50000并且保证所有k之和<=2* ...

  6. bzoj 3551 [ONTAK2010]Peaks加强版(kruskal,主席树,dfs序)

    Description [题目描述]同3545 Input 第一行三个数N,M,Q. 第二行N个数,第i个数为h_i 接下来M行,每行3个数a b c,表示从a到b有一条困难值为c的双向路径. 接下来 ...

  7. 2018.11.01 NOIP训练 图论(线段树+倍增+dfs序)

    传送门 一道挺妙的题. 对于询问点(u,v),如右图所示,我们可以发现存在一个点m在u->v的路径中,m子树的点到u是最近的,m子树外到v是最近的.其中dis(u,m)=(dis(u,v)-1) ...

  8. 线段树(dfs序建树加区间更新和单点查询)

    题目链接:https://cn.vjudge.net/contest/66989#problem/J 记录一下这道折磨了我一天的题,.... 具体思路: 具体关系可通过dfs序建树,但是注意,在更新以 ...

  9. bzoj3306: 树(dfs序+倍增+线段树)

    比较傻逼的一道题... 显然求子树最小值就是求出dfs序用线段树维护嘛 换根的时候树的形态不会改变,所以我们可以根据相对于根的位置分类讨论. 如果询问的x是根就直接输出整棵树的最小值. 如果询问的x是 ...

随机推荐

  1. UTI iPhone支持依文件后缀名打开应用

    本文转载至 http://blog.csdn.net/zaitianaoxiang/article/details/6658492 iphoneapplicationprocessingfileurl ...

  2. 【BZOJ2770】YY的Treap 结论+线段树

    [BZOJ2770]YY的Treap Description 志向远大的YY小朋友在学完快速排序之后决定学习平衡树,左思右想再加上SY的教唆,YY决定学习Treap.友爱教教父SY如砍瓜切菜般教会了Y ...

  3. ST表(离线RMQ)

    离线RAQ时,预处理为O(n*lgn),查询为O(1)的算法,比较有意思的一种算法 放个模板在这可以随时看 //ST表(离线) //预处理 O(n*lgn) , 查询 O(1) #include &l ...

  4. 巨蟒python全栈开发django13:中间件部分

    1.回顾昨日内容 2.session认证装饰器 3.django整个流程 4.中间件简单应用 5.简单统计访问次数 6.中间件其他方法 7.orm单表内容回顾

  5. Quartz实现定时功能

    ---------------------------------博主讲废话 在自己实现爬取某个网站的信息后,发现,如果要自己每次把程序跑一遍不太现实(麻烦),所以有没有什么可以实现 定时的功能,只要 ...

  6. (4.9)SQL Server如何校验备份文件

    译 SQL Server如何校验备份文件 转自:https://blog.csdn.net/tjvictor/article/details/5261666 RESTORE VERIFYONLY与 c ...

  7. 006-重装yum

    报错情况: There was a problem importing one of the Python modulesrequired to run yum. The error leading ...

  8. 《Python机器学习》笔记(三)

    使用scikit-learning 实现机器学习分类算法 分类算法的选择 没有免费的午餐理论:没有任何一种分类器可以在所有可能的应用场景下都有良好的表现. 实践证明,只有比较了多种学习算法的性能,才能 ...

  9. 20170413 F110学习

                  F110 学习: Tcode: F110  自动付款业务, FBZP   维护收付程序设置 FBL1N   供应商行项目 XK03   显示供应商(银行信息维护) F110 ...

  10. PyQt4 UI设计和调用 使用eric6

    使用工具eric6 安装包地址: http://eric-ide.python-projects.org/eric-download.html 1.需要安装python和pyqt为前提,然后安装eri ...