补两个题
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