补几个题

补两个题

A 谍报分析
我写了字典树,虽然对于这个数据范围完全没必要

#include<cstdio>
#include<cstring>
using namespace std;

struct node{
    int cnt;
    node *ch[26];
    node (){cnt=0;for(int i=0;i<26;i++) ch[i]=NULL;}
}root;
char str[50005],*p,s[10][100];int num[10],len[10],used[10];
void add(){
    while(*p&&!('a'<=*p&&*p<='z')) p++;
    if(!*p) return ;
    if(*(p-1)=='\\'&&*p=='n') p++;
    char *star=p;
    node *z=&root;
    for(;'a'<=*p&&*p<='z';p++){
        if(z->ch[*p-'a']) z=z->ch[*p-'a'];
        else{
            node *pn=new node;
            z->ch[*p-'a']=pn;
            z=pn;
        }
    }
    if(z==&root) return ;
    z->cnt++;
    char c=*p;*p=0;
    for(int i=0;i<10;i++){
        if(len[i]!=p-star) continue;
        if(!strcmp(star,s[i])){
            num[i]=z->cnt;
            *p=c;
            return ;
        }
    }
    int v=-1;
    for(int i=0;i<10;i++){
        if((z->cnt > num[i] || z->cnt == num[i] && strcmp(star,s[i]) > 0 )
            &&(v==-1||num[v]>num[i]||(num[v]==num[i]&&strcmp(s[v],s[i]) < 0)))
        {
            v=i;
        }
    }
    if(v!=-1){
        len[v]=p-star;
        num[v]=z->cnt;
        strcpy(s[v],star);
    }
    *p=c;
}
int main()
{
//  freopen("C:\\Users\\chutzpah\\Desktop\\in.txt","r",stdin);
    fread(str,50000,1,stdin);
    p=str;
    while(*p) add();
    for(int i=0;i<10;i++){
        int v=-1;
        for(int j=0;j<10;j++){
            if(used[j]) continue;
            if(v==-1||num[v]<num[j]||num[v]==num[j]&&strcmp(s[j],s[v])<0) v=j;
        }
        used[v]=true;
        printf("%s %d\n",s[v],num[v]);
    }
    return 0;
}

B 情报传递
小技巧:删除的时候标记该节点即可而没必要向下递归(写向下递归应该会多很多代码吧)

#include<stdio.h>

const int MAXN = 5e4 + 100;
int par[MAXN], tag[MAXN], N, M;

int main()
{
    while(scanf("%d",&N)!=EOF){
        for(int i=1;i<N;i++) {
            tag[i]=0;
            scanf("%d", &par[i]);
        }
        scanf("%d", &M);
        for(int i=0;i<M;i++){
            char op[10];int x,ans=0;
            scanf("%s %d",op,&x);
            if(*op=='S'){
                int cnt=0,t=0;
                while(!(x==0&&x==par[x]&&tag[x]!=0)){
                    if(tag[x]) t++;
                    else ans+=t+1,t=0;
                    tag[x]+=++cnt;
                    x=par[x];
                }
                printf("%d\n",ans);
            }else{
                printf("%d\n",tag[x]);
                tag[x]=0;
            }
        }
    }
    return 0;
}

题目链接 http://218.28.220.249:50015/JudgeOnline/contest.php?cid=1024

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值