• 联考20200801 T2 皮卡丘





    分析:
    整体思路是,没有被走到的点我们直接数学计算,走到的点暴力维护
    考虑对每次探索操作维护二叉树,由于每个点在没有被删的情况下为自然生长,其出现时间就是它的深度,而被炸掉的点会在目前时间的下一刻长出来
    我们在被炸掉的点上打上时间标记,表示这个点多久后才会长出来
    每次向下探索时,维护路径上的时间差(这个点长出来的时间减去这个点本应长出来的时间),用于统计子树内因删除而没有长出来的节点
    维护全局变量\(Sz\)\(Lf\)表示总节点数和叶子个数,生长时通过数学计算更新,删除时在建出来的二叉树上寻找删除的大小来更新
    总时间复杂度为\(O(n+\sum|S|)\)

    #include<cstdio>
    #include<cstring>
    #include<cmath>
    #include<algorithm>
    
    #define maxn 1000005
    #define MOD 998244353
    #define inv2 499122177
    
    using namespace std;
    
    inline long long getint()
    {
    	long long num=0,flag=1;char c;
    	while((c=getchar())<'0'||c>'9')if(c=='-')flag=-1;
    	while(c>='0'&&c<='9')num=num*10+c-48,c=getchar();
    	return num*flag;
    }
    
    int n,Tim;
    int pw[maxn];
    int ch[maxn][2],tim[maxn],tot;
    int Lf,Sz,wp,wl,L;
    char op[maxn];
    
    inline void update(int &u,int p,int ldt)
    {
    	if(!u)
    	{
    		if(Tim-ldt-p+1>=0)wp=(wp+pw[Tim-ldt-p+1]-1)%MOD;
    		if(Tim-ldt-p>=0)wl=(wl+pw[Tim-ldt-p])%MOD;
    		return;
    	}
    	if(Tim-ldt-p>0)wp++;
    	if(tim[u]!=-1)ldt=max(ldt,tim[u]-p);
    	update(ch[u][0],p+1,ldt),update(ch[u][1],p+1,ldt);
    	u=0;
    }
    
    inline void dfs(int u,int p,int ldt)
    {
    	if(tim[u]!=-1)ldt=max(ldt,tim[u]-p);
    	if(p==L)
    	{
    		wp=wl=0;
    		if(Tim-ldt-p<=0)wl=1;
    		update(ch[u][0],p+1,ldt),update(ch[u][1],p+1,ldt);
    		Sz=(Sz-wp-1)%MOD;
    		Lf=(Lf-wl+inv2)%MOD;
    		tim[u]=Tim+1;
    		return;
    	}
    	int d=(op[p]=='R');
    	if(!ch[u][d])ch[u][d]=++tot,tim[ch[u][d]]=-1,ch[tot][0]=ch[tot][1]=0;
    	dfs(ch[u][d],p+1,ldt);
    }
    
    int main()
    {
    	freopen("pikachu.in","r",stdin);
    	freopen("pikachu.out","w",stdout);
    
    	int T=getint();
    	pw[0]=1;
    	for(int i=1;i<maxn;i++)pw[i]=2*pw[i-1]%MOD;
    	memset(tim,-1,sizeof tim);
    	while(T--)
    	{
    		n=getint();
    		Lf=Sz=1,tot=Tim=0;
    		ch[0][0]=ch[0][1]=0;
    		while(n--)
    		{
    			scanf("%s",op);
    			if(op[0]=='G')
    			{
    				int x=getint();
    				Tim+=x;
    				Sz=(Sz+1ll*Lf*(pw[x+1]-2))%MOD;
    				Lf=1ll*Lf*pw[x]%MOD;
    			}
    			else scanf("%s",op),L=strlen(op),dfs(0,0,0);
    			printf("%d\n",(Sz+MOD)%MOD);
    		}
    	}
    }
    

  • 相关阅读:
    npm ci命令比npm installer命令快2至10倍
    Liferay 7.1发布啦
    2016/07/05 zend optimizer
    2016/06/16 phpexcel
    2016/06/13 phpexcel 未完待续
    2016/06/10 日历插件 Datepicker
    2016/06/09 ThinkPHP3.2.3使用分页
    2016/06/02 网摘记录 svn 服务器端 客户端 安装使用
    2016/05/27 php上传文件常见问题总结
    2016/05/25 抽象类与API(接口)差别
  • 原文地址:https://www.cnblogs.com/IzayoiDoyo/p/13422987.html
Copyright © 2020-2023  润新知