zoukankan      html  css  js  c++  java
  • 联考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
    ",(Sz+MOD)%MOD);
    		}
    	}
    }
    

  • 相关阅读:
    js正则表达式中的问号使用技巧总结
    380. Insert Delete GetRandom O(1)
    34. Find First and Last Position of Element in Sorted Array
    162. Find Peak Element
    220. Contains Duplicate III
    269. Alien Dictionary
    18. 4Sum
    15. 3Sum
    224. Basic Calculator
    227. Basic Calculator II
  • 原文地址:https://www.cnblogs.com/Darknesses/p/13422987.html
Copyright © 2011-2022 走看看