当前位置:编程学习 > 网站相关 >>

高级打字机 (Tries)

Problem 1 高级打字机(type.cpp/c/pas)
【题目描述】
早苗入手了最新的高级打字机。最新款自然有着与以往不同的功能,那就是它具备撤销功能,厉害吧。
请为这种高级打字机设计一个程序,支持如下3种操作:
1.T x:在文章末尾打下一个小写字母x。(type操作)
2.U x:撤销最后的x次修改操作。(Undo操作)
(注意Query操作并不算修改操作)
3.Q x:询问当前文章中第x个字母并输出。(Query操作)
文章一开始可以视为空串。
 
【输入格式】
第1行:一个整数n,表示操作数量。
以下n行,每行一个命令。保证输入的命令合法。
 
【输出格式】
每行输出一个字母,表示Query操作的答案。
 
【样例输入】
7
T a
T b
T c
Q 2
U 2
T c
Q 2
【样例输出】
b
c
【数据范围】
对于40%的数据 n<=200;
对于100%的数据 n<=100000;保证Undo操作不会撤销Undo操作。
<高级挑战>
对于200%的数据 n<=100000;Undo操作可以撤销Undo操作。
<IOI挑战>
必须使用在线算法完成该题。

这题要用字典树(Tries)
还有msm(倍增算法)

另外 补充一点
char  s[0]   或者 char
scanf("%s",s)
 这句会存不下"\0"
因此会把正在循环的自变量i 变成 0

[cpp]
#include<cstdio> 
#include<cstring> 
#include<cstdlib> 
#include<iostream> 
#include<cmath> 
#include<vector> 
#include<cctype> 
using namespace std; 
#define MAXN (100000+10) 
#define LOGMAXN (16+10) 
int n,tot=0; 
struct Tnode 

    int deep,f[LOGMAXN]; 
    char edge; 
    Tnode() 
    { 
        memset(f,0,sizeof(f)); 
        deep=-1; 
        edge='\0'; 
    } 
    Tnode(char _edge,int _fa,int _deep) 
    { 
        memset(f,0,sizeof(f)); 
        f[0]=_fa; 
        edge=_edge; 
        deep=_deep;  
    } 
    int logdeep() 
    { 
        return int(trunc(log(deep)/log(2))); 
    }    
}node[MAXN]; 
int log2(int a) 

    return int(trunc(log(a)/log(2))); 

void msm(Tnode &a) 

    int n=a.logdeep(); 
//  if (n==1) return; 
    for (int i=1;i<=n;i++) 
    { 
        a.f[i]=node[a.f[i-1]].f[i-1]; 
    }    

void type() 

    char c; 
    scanf("%s",&c); 
    tot++; 
    node[tot]=Tnode(c,tot-1,node[tot-1].deep+1); 
    msm(node[tot]); 

 
void quere() 

    int p; 
    scanf("%d",&p); 
    Tnode now=node[tot]; 
    p=now.deep+1-p; //第i's 祖先  
    while (p) 
    { 
        int i=log2(p); 
        p-=(1<<i); 
        now=node[now.f[i]]; 
                         
    } 
    printf("%c\n",now.edge);  
      

void undo() 

    int p; 
    scanf("%d",&p); 
    tot++; 
    node[tot]=node[tot-1-p]; 

int main() 

    freopen("type.in","r",stdin); 
    freopen("type.out","w",stdout); 
    scanf("%d",&n); 
    node[0]=Tnode(); 
    for (int ii=1;ii<=n;ii++) 
    { 
//      printf("%d\n",ii); 
        char s[10]; 
//      printf("%d\n",ii); 
        scanf("%s",s); 
//      printf("%d\n",ii); 
//      while(1); 
        switch(s[0]) 
        { 
            case 'T':type();break; 
            case 'U':undo();break; 
            case 'Q':quere();break;          
        } 
         
         
    }    
//  while (1); 
    return 0; 

补充:综合编程 , 其他综合 ,
CopyRight © 2012 站长网 编程知识问答 www.zzzyk.com All Rights Reserved
部份技术文章来自网络,