树的dfs序 && 系统栈 && c++ rope
利用树的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的更多相关文章
- [2]树的DFS序
定义: 树的DFS序就是在对树进行DFS的时候,对树的节点进行重新编号:DFS序有一个很强的性质: 一颗子树的所有节点在DFS序内是连续的一段, 利用这个性质我们可以解决很多问题. 代码: void ...
- CF877E Danil and a Part-time Job 线段树维护dfs序
\(\color{#0066ff}{题目描述}\) 有一棵 n 个点的树,根结点为 1 号点,每个点的权值都是 1 或 0 共有 m 次操作,操作分为两种 get 询问一个点 x 的子树里有多少个 1 ...
- HDU4117 GRE WORDS(AC自动机+线段树维护fail树的dfs序)
Recently George is preparing for the Graduate Record Examinations (GRE for short). Obviously the mos ...
- 【BZOJ2286】消耗战(虚树,DFS序,树形DP)
题意:一棵N个点的树上有若干个关键点,每条边有一个边权,现在要将这些关键点到1的路径全部切断,切断一条边的代价就是边权. 共有M组询问,每组询问有k[i]个关键点,对于每组询问求出完成任务的最小代价. ...
- 【BZOJ3611】大工程(虚树,DFS序,树形DP)
题意:有一棵树,树有边权,有若干次询问,给出一些点,求: 1.这些点互相之间的距离之和 2.点对距离中的最大和最小值 n<=1000000 q<=50000并且保证所有k之和<=2* ...
- bzoj 3551 [ONTAK2010]Peaks加强版(kruskal,主席树,dfs序)
Description [题目描述]同3545 Input 第一行三个数N,M,Q. 第二行N个数,第i个数为h_i 接下来M行,每行3个数a b c,表示从a到b有一条困难值为c的双向路径. 接下来 ...
- 2018.11.01 NOIP训练 图论(线段树+倍增+dfs序)
传送门 一道挺妙的题. 对于询问点(u,v),如右图所示,我们可以发现存在一个点m在u->v的路径中,m子树的点到u是最近的,m子树外到v是最近的.其中dis(u,m)=(dis(u,v)-1) ...
- 线段树(dfs序建树加区间更新和单点查询)
题目链接:https://cn.vjudge.net/contest/66989#problem/J 记录一下这道折磨了我一天的题,.... 具体思路: 具体关系可通过dfs序建树,但是注意,在更新以 ...
- bzoj3306: 树(dfs序+倍增+线段树)
比较傻逼的一道题... 显然求子树最小值就是求出dfs序用线段树维护嘛 换根的时候树的形态不会改变,所以我们可以根据相对于根的位置分类讨论. 如果询问的x是根就直接输出整棵树的最小值. 如果询问的x是 ...
随机推荐
- EasyNVR智能云终端硬件使用说明(EasyNVR无插件直播服务硬件的具体使用方法)
问题背景 随着EasyNVR硬件版本(EasyNVR硬件云终端)的发布不少客户选择了EasyNVR云终端作为产品选择,在客户收到EasyNVR云终端的时候肯定都有一个疑问,那就是如何使用手头上的这个小 ...
- 母版页改变被嵌套的页面中的控件ID的解决方法
使用过模板页的朋友都会很纳闷,怎么页面的用js通过getElementById(“id”):找不到对象.查看了页面源代码才发现,原来控件的ID变了,这是母版页导致的.因为母版页怕母版页本身页面中的控件 ...
- 初步认识dubbo--小案例
Dubbo是Alibaba开源的分布式服务框架,它最大的特点是按照分层的方式来架构,使用这种方式可以使各个层之间解耦合(或者最大限度地松耦合).从服务模型的角度来看,Dubbo采用的是一种非常简单的模 ...
- Linux下Solr的安装和配置
一.安装 1.需要的安装包:apache-tomcat-7.0.47.tar.gz.solr-4.10.3.tgz.tgz(jdk自行安装) 2.解压tomcat并创建solr文件夹 [root@lo ...
- JavaScript遍历IP段内所有IP
思路:将两个IP转换为数字进行比较,小的那个慢慢加一,直到变成大的那个IP所转换的数字,将这其中的数字再转换为IP地址即为IP段内所有的IP. //IP转数字 function ip2int(ip) ...
- AJAX 入门
1. 同步交互与异步交互 1.1 同步交互 客户端发送一个请求, 需要等待服务器的响应结束,才能发送第二个请求! 刷新的是整个页面. 1.2 异步交互 客户端发送一个请求,无需等待服务器的响应,然后就 ...
- Service 事务(JdbcUtils 升级)
1. DAO 事务 // 在 DAO 中处理事务真是"小菜一碟" public void xxx(){ Connection con = null; try{ con = Jdbc ...
- Axure快捷键
基本快捷键: 打开:Ctrl + O 新建:Ctrl + N 保存:Ctrl + S 退出:Alt + F4 打印:Ctrl + P 查找:Ctrl + F 替换:Ctrl + H 复制:Ctrl + ...
- PowerDesigner数据模型(CDM—PDM)
操作过程 点击: Tools/Generate Physical Data Model
- Kafka的架构
1.Kafka整体架构 一个典型的Kafka集群中包含若干producer(可以是web前端产生的page view,或者是服务器日志,系统CPU.memory等),若干broker(Kafka ...