zoukankan      html  css  js  c++  java
  • 树的dfs序 && 系统栈 && c++ rope

    利用树的dfs序解决问题:

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

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

      1 #include <cstdio>
      2 #include <cstdlib>
      3 #include <cstring>
      4 #include <algorithm>
      5 #include <iostream>
      6 #include <stack>
      7 //#pragma comment(linker,"/STACK:1024000000,1024000000")
      8 using namespace std;
      9 #define MAXN (200000+10)
     10 #define lowbit(i) (i&(-i))
     11 int n,m;
     12 struct BIT{
     13     int t[MAXN];
     14     BIT(){memset(t,0,sizeof(t));}
     15     void init(){memset(t,0,sizeof(t));}
     16     int _query(int a){
     17         int ans=0;
     18         for (int i=a;i>=1;i-=lowbit(i))    ans+=t[i];
     19         return ans;
     20     }
     21     void modify(int a,int x){
     22         for (int i=a;i<=n;i+=lowbit(i))    t[i]+=x;
     23     }
     24     
     25     int query(int a,int b){
     26         return _query(b)-_query(a-1);
     27     }
     28 }T;
     29 int timemark;
     30 int intime[MAXN],outime[MAXN];
     31 int data[MAXN];
     32 int f[MAXN];
     33 int head[MAXN],next[MAXN],e[MAXN],countside;
     34 void buildside(int a,int b){
     35     e[countside]=b;
     36     next[countside]=head[a];
     37     head[a]=countside++;
     38 }
     39 /*
     40 void dfs(int x,int fa){
     41     intime[x]=timemark++;
     42     for (int i=head[x];i>0;i=next[i]){
     43         if (e[i]!=fa){
     44             dfs(e[i],x);
     45         }
     46     }
     47     outime[x]=timemark++;
     48 }
     49 */
     50 
     51 stack<int> s;
     52 bool instack[MAXN];
     53 void dfs(int root){
     54     memset(instack,false,sizeof instack);
     55     s.push(root);
     56     intime[root]=timemark++;
     57     instack[root]=true;
     58     while (!s.empty()){
     59         bool loop=false;
     60         int now=s.top();
     61         for (int i=head[now];i>0;i=next[i]){
     62             if (!instack[e[i]]){
     63                 s.push(e[i]);
     64                 instack[e[i]]=true;
     65                 intime[e[i]]=timemark++;
     66                 loop=true;
     67                 break;
     68             }
     69         }
     70         if (loop)    continue;
     71         s.pop();
     72         outime[now]=timemark++;
     73     }
     74 }
     75 
     76 int main (int argc, char *argv[])
     77 {
     78     int p;
     79     int a,b;
     80     char cmd[10];
     81     
     82     while (1){
     83         scanf("%d%d",&n,&p);
     84     
     85         if (n==0 && p==0)    break;
     86     
     87         memset(head,0,sizeof head);
     88         memset(next,0,sizeof next);
     89         memset(e,0,sizeof e);    
     90     
     91         countside=1;
     92         for (int i=1;i<=n-1;i++){
     93             scanf("%d%d",&a,&b);
     94             buildside(a,b);
     95             buildside(b,a);
     96         }
     97     
     98         timemark=1;
     99         dfs(p);
    100     
    101     
    102         /*for (int i=1;i<=n;i++)    cout<<intime[i]<<" "<<outime[i]<<endl;*/
    103     
    104         int N=n;
    105         n=n*2;
    106         T.init();
    107         for (int i=1;i<=n;i++){
    108             data[i]=1;
    109             T.modify(i,1);
    110         }
    111     
    112         for (int i=N;i>=1;i--){
    113             f[i]=(T.query(intime[i],outime[i])-2)/2;
    114             T.modify(intime[i],-1);
    115             T.modify(outime[i],-1);
    116         }
    117     
    118         for (int i=1;i<=N-1;i++)    printf("%d ",f[i]);
    119         printf("%d
    ",f[N]);
    120     }
    121     return 0;
    122 }
    View Code

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

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

    WTF。。。涨姿势了

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

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

    NOI 的那道文本编辑器

     1 #include <iostream>
     2 #include <cstring>
     3 #include <cstdlib>
     4 #include <cstdio>
     5 #include <ext/rope>
     6 using namespace std;
     7 using namespace __gnu_cxx;
     8 crope List;
     9 int n,now,k;
    10 char s[2500005];
    11 int main()
    12 {
    13     char cmd[25];
    14     int i;
    15     for (scanf("%d",&n);n--;)
    16     {
    17         scanf("%s",cmd);
    18         if (cmd[0]=='M') scanf("%d",&now);
    19         else if (cmd[0]=='I')
    20         {
    21             scanf("%d%*c",&k);
    22             for (i=0;i<k;i++) do
    23             {
    24                 scanf("%c",&s[i]);
    25             }while(s[i]=='
    ');
    26             s[k]=0;
    27             List.insert(now,s);
    28         }
    29         else if (cmd[0]=='D')
    30         {
    31             scanf("%d",&k);
    32             List.erase(now,k);
    33         }
    34         else if (cmd[0]=='G')
    35         {
    36             scanf("%d",&k);
    37             List.copy(now,k,s);
    38             s[k]=0;
    39             puts(s);
    40         }
    41         else if (cmd[0]=='P') now--;
    42         else now++;
    43     }
    44     return 0;
    45 }
    View Code
  • 相关阅读:
    开通博客第一天
    Vue 打包配置productionSourceMap 的记录
    supervisorctl 的 简单记录
    mvn打包方式记录
    springboot日志配置,关于logback
    springboot集成swagger
    关于mapper文件的bean
    elasticsearch 连接、操作记录
    关于前后端分离文件上传的些许问题
    代码优化--策略模式的四种表现
  • 原文地址:https://www.cnblogs.com/loveidea/p/3906417.html
Copyright © 2011-2022 走看看