利用树的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. 【BZOJ2555】SubString 后缀自动机+LCT

    [BZOJ2555]SubString Description 懒得写背景了,给你一个字符串init,要求你支持两个操作         (1):在当前字符串的后面插入一个字符串         (2 ...

  2. 在Visual Studio 2015的Cordova项目中使用Gulp

    之前一直是在vs 2013中使用Cordova来开发移动app(目前有iPad版/iPhone版/安卓版),准备到下一个milestone的时候升级到2015,这两天在尝试各种东西. 2015中的co ...

  3. 防sql注入之参数绑定 SQL Injection Attacks and Defense

    http://php.net/manual/zh/pdo.prepared-statements.php 预处理语句与存储过程 很多更成熟的数据库都支持预处理语句的概念.什么是预处理语句?可以把它看作 ...

  4. Webshell清除-解决驱动级文件隐藏挂马

    Webshell清除-解决驱动级文件隐藏挂马

  5. JavaScript深入理解sort()方法

    一. 基本用法 let arr1 = [3, 5, 7, 1, 8, 7, 10, 20, 19] console.log(arr1.sort()) // [1, 10, 19, 20, 3, 5, ...

  6. 一、Nuxt简介

    1.Nuxt是什么    Nuxt.js是基于vue的服务器端渲染框架,常用来做SSR(服务器端渲染)   2.为什么用Nuxt    Vue开发的SPA(单页应用)不利于搜索引擎的SEO优化   3 ...

  7. If you ever have a broken heart

    If you ever have a broken heart Pablo Neruda Tonight i can write the saddest lines Write ,for exampl ...

  8. 剑指offer 面试40题

    面试40题: 题目:最小的k个数 题:输入n个整数,找出其中最小的K个数.例如输入4,5,1,6,2,7,3,8这8个数字,则最小的4个数字是1,2,3,4,. 解题代码一: # -*- coding ...

  9. PictureBox 双缓冲防止闪屏

    Bitmap bm = new Bitmap(this.pbTraffic.Image); BufferedGraphicsContext current = BufferedGraphicsMana ...

  10. Serv-u 外网访问内网的FTP服务器

    1. 背景简介 最近研究如何在内网搭架FTP服务器,同时要保证外网(公网)能访问的到.终成正果,但走了一些弯路,在此记下,以飨后人. 2. 基础知识 FTP 使用 2 个端口,一个数据端口和一个命令端 ...