北京培训 DAY7

早上讲COCI,即克罗地亚的IOI选拔赛的题  

一下子就蠢了一早上 = =  发现好多题都是在学校里的NOIP模拟赛中做到过的  到底学校的NOIP模拟赛是什么难度啊啊啊啊啊- -

具体题目就不说了

下午是ACM赛制的一次比赛  挺有趣的  据说前三名的队伍有奖品  五个小时十道题

一开始题目的数据没有配好 怎么交都只要编译通过就是AC  开始两个小时还以为自己写的都是对的= =  后来改会来再交发现WA了一万道  只好慢慢改  不过最后还是有前三 感觉不错

就这样吧

北京培训 DAY6

啦啦啦  种太阳~~~

早上题目据说是可选不做的 = = 但是我还是去写了(我真是无聊)

第一题 

莫比乌斯反演+找规律 题解在这里 自己看吧

链接:

第二题 

给一个字符串集合 支持将集合中的串i删除或加入 查询给定一个串S 这个集合中的字符串在S中出现次数

写了一早上没调出来 到了中午才终于弄出来 = = 

对集合建一个AC-automaton(这里每个点的结尾标记不可合并)然后再以fail指针连边新建一棵fail树 每个点的权值为AC-automaton中的标记值 然后每次转移时访问这个结点在fail树中对应结点到根路径上的权值和 以DFS序+树状数组维护 完成~

贴个代码纪念一下

#include <iostream>
#include <cstdlib>
#include <cstring>
#include <string>
#include <cstdio>
#include <queue>
using namespace std;

const int Size=26,maxn=1000086;

int n,m,f[maxn][2],num,ans,head[maxn*2],num_edge,seq[maxn*2],now_node,len
	,corres[maxn][2],val[maxn],sum[maxn*4],end[maxn];
char s[maxn],order;
bool visit[maxn],use[maxn];

struct AC_automaton
{
	struct Node
	{
		int next[Size+1];
		int fail;
		int father;
		int val;
		int flag;
	}node[maxn];
	
	int num_node,root,qs[maxn];
	
	AC_automaton()
	{
		num_node=root=0;
		node[root].val=0;
	}
	
	int get_num(char a)
	{
		return int(a-'a'+1);
	}
	
	void insert(int pos)
	{
		int now_pos,len_s=strlen(s);
		now_pos=0;
		for(int i=0;i<len_s;i++)
		{
			if(!node[now_pos].next[get_num(s[i])])
			{
				node[now_pos].next[get_num(s[i])]=++num_node;
				node[num_node]=(Node){{0},0,now_pos,get_num(s[i]),0};
			}
			now_pos=node[now_pos].next[get_num(s[i])];
		}
		node[now_pos].flag++;
		end[pos]=now_pos;
	}
	
	int get_fail(int now,int val)
	{
		if(node[now].next[val])return node[now].next[val];
		if(now==0)return 0;
		int tmp=get_fail(node[now].fail,val);
		return tmp;
	}
	
	void build_fail()
	{
		int tmp,l=1,r=0;
		qs[++r]=0;
		while(l<=r)
		{
			tmp=qs[l++];
			if(!node[tmp].father)node[tmp].fail=0;
			else node[tmp].fail=get_fail(node[node[tmp].father].fail,node[tmp].val);
			for(int i=1;i<=Size;i++)
				if(node[tmp].next[i])
					qs[++r]=node[tmp].next[i];
		}
	}
	
	int get_next_node(int now,int val)
	{
		while((now!=0)&&(!node[now].next[val]))	now=node[now].fail;
		if(node[now].next[val]!=0)return node[now].next[val];
		return 0;
	}
}T;

struct Edge
{
	int next;
	int to;
}edge[maxn*2];

void add_edge(int from,int to)
{
	edge[++num_edge].next=head[from];
	edge[num_edge].to=to;
	head[from]=num_edge;
}

struct T_T
{
	int now;
	int next;
}istack[maxn],tmp;

void get_seq()
{
	int top=1;
	istack[1].now=1;
	istack[1].next=head[1];
	seq[++len]=0;
	visit[1]=1;
	corres[0][0]=1;
	while(top)
	{
		tmp=istack[top--];
		if(tmp.next==0)
		{
			corres[tmp.now-1][1]=len+1;
			continue;
		}
		visit[edge[tmp.next].to]=1;
		istack[++top]=(T_T){tmp.now,edge[tmp.next].next};
		istack[++top]=(T_T){edge[tmp.next].to,head[edge[tmp.next].to]};
		seq[++len]=edge[tmp.next].to-1;
		corres[edge[tmp.next].to-1][0]=len;
	}
}

inline int lowbit(int u){return (u&(-u));}

void add_num(int pos,int num)
{
	for(int i=pos;i<=maxn*2;i+=lowbit(i))sum[i]+=num;
}

int get_sum(int pos)
{
	int tmp=0;
	for(int i=pos;i>0;i-=lowbit(i))tmp+=sum[i];
	return tmp;
}

int main()
{
	scanf("%d %d",&m,&n);
	for(int i=1;i<=n;i++)
	{
		scanf("%s",s);
		T.insert(i);
	}
	T.build_fail();
	for(int i=1;i<=T.num_node;i++)
	{
		add_edge(T.node[i].fail+1,i+1);
		val[i]=T.node[i].flag;
	}
	for(int i=1;i<=n;i++)use[i]=1;
	get_seq();
	for(int i=0;i<=T.num_node;i++)
	{
		add_num(corres[i][0],val[i]);
		add_num(corres[i][1],-val[i]);
	}
	for(int i=1;i<=m;i++)
	{
		scanf("\n%c",&order);
		if(order=='-')
		{
			scanf("%d",&num);
			if(use[num])
			{
				use[num]=0;
				val[end[num]]--;
				add_num(corres[end[num]][0],-1);
				add_num(corres[end[num]][1],1);
			}
		}
		else if(order=='+')
		{
			scanf("%d",&num);
			if(!use[num])
			{
				use[num]=1;
				val[end[num]]++;
				add_num(corres[end[num]][0],1);
				add_num(corres[end[num]][1],-1);
			}
		}
		else
		{
			ans=now_node=0;
			scanf("%s",s);
			len=strlen(s);
			for(int i=0;i<len;i++)
			{
				now_node=T.get_next_node(now_node,s[i]-'a'+1);
				ans+=get_sum(corres[now_node][0]);
			}
			printf("%d\n",ans);
		}
	}
	return 0;
}

然后是第三题 据说是三题中最简单的  是一个DP

题目就贴链接算了:

题解也贴链接算了:

下午讲了下题解 结束

————————The End——————————