zoukankan      html  css  js  c++  java
  • 6377. 【NOIP2019模拟2019.10.05】幽曲[埋骨于弘川]

    题目描述




    题解

    随便bb

    详细题解见
    https://www.cnblogs.com/coldchair/p/11624979.html
    https://blog.csdn.net/alan_cty/article/details/84557477
    https://www.cnblogs.com/Iking123/p/11626041.html

    这里讲讲自己发现的东西和一些细节

    f[i][p][a]表示第i位以后(包括第i位)的最大值,a表示个位,在第i为进1的个位会变成什么

    为什么要包括第i位呢,因为假设的进位不会影响到p,所以考虑上包括的情况都一样

    而且可以适应第i位不为0的情况,更严谨一些

    g[i][p][x][a]的x表示第i位放x后个位会变成什么,只需要进x次位就行了

    当i=1时要特殊考虑(考虑能否放x)

    至于f和g的取值是否重复,显然不会不然怎么做

    把方程列出来后可以发现结果其实是存在原来的状态上的,所以不会重复不然就是列错了

    dp[i][j][p][a]表示dfs序为i,做到第j位的方案数

    转移前缀和优化,可以直接把dp[i]设为原来的dp[1..i]

    要考虑i=1和j=1

    code

    #include <algorithm>
    #include <iostream>
    #include <cstdlib>
    #include <cstring>
    #include <cstdio>
    #define fo(a,b,c) for (a=b; a<=c; a++)
    #define fd(a,b,c) for (a=b; a>=c; a--)
    #define add(a,b) (a=(a+(b)%998244353)%998244353)
    #define min(a,b) (a<b?a:b)
    #define max(a,b) (a>b?a:b)
    #define mod 998244353
    using namespace std;
    
    struct type{
    	int x,y;
    } E[1001];
    int a[1001][2];
    int ls[501];
    int f[501][10][10];     //f[i][p][a] p=max in [>=i] a=the first
    int g[501][10][10][10]; //g[i][p][x][a]
    int dp[501][501][10][10]; //dp[i][j][p][a]
    int st[501];
    int d[501];
    int fa[501];
    int N,A,n,K,I,i,j,k,l,len;
    long long ans;
    
    bool cmp(type a,type b)
    {
    	return a.x<b.x || a.x==b.x && a.y>b.y;
    }
    
    void New(int x,int y)
    {
    	++len;
    	a[len][0]=y;
    	a[len][1]=ls[x];
    	ls[x]=len;
    }
    
    void dfs(int Fa,int t)
    {
    	int i;
    	
    	fa[t]=Fa;
    	st[t]=++N;
    	
    	for (i=ls[t]; i; i=a[i][1])
    	if (a[i][0]!=Fa)
    	dfs(t,a[i][0]);
    }
    
    void Dfs(int Fa,int t)
    {
    	int i,j,k,l;
    	
    	i=st[t];
    	fo(j,1,n)
    	{
    		fo(k,0,K-1)
    		{
    			fo(l,0,K-1)
    			dp[i][j][k][l]=dp[i-1][j][k][l];
    		}
    	}
    	
    	fo(j,1,n)
    	{
    		fo(k,0,K-1)
    		{
    			fo(l,0,K-1)
    			{
    				if (j>1)
    				{
    					if (t>1)
    					add(dp[i][j-1][max(k,d[t])][g[j][k][d[t]][l]],dp[i-1][j][k][l]-dp[st[fa[t]]-1][j][k][l]);
    					else
    					add(dp[i][j-1][max(k,d[t])][g[j][k][d[t]][l]],dp[i-1][j][k][l]);
    				}
    				else
    				if (g[j][k][d[t]][l]>-1)
    				{
    					if (t>1)
    					add(ans,dp[i-1][j][k][l]-dp[st[fa[t]]-1][j][k][l]);
    					else
    					add(ans,dp[i-1][j][k][l]);
    				}
    			}
    		}
    	}
    	
    	for (i=ls[t]; i; i=a[i][1])
    	if (a[i][0]!=Fa)
    	Dfs(t,a[i][0]);
    }
    
    int main()
    {
    	freopen("buried.in","r",stdin);
    	freopen("buried.out","w",stdout);
    	
    	scanf("%d%d",&n,&K);
    	fo(i,1,n)
    	scanf("%d",&d[i]);
    	fo(i,2,n)
    	{
    		scanf("%d%d",&j,&k);
    		
    		E[++l]={j,k};
    		E[++l]={k,j};
    	}
    	
    	sort(E+1,E+l+1,cmp);
    	
    	fo(i,1,l)
    	New(E[i].x,E[i].y);
    	
    	memset(f,255,sizeof(f));
    	memset(g,255,sizeof(g));
    	
    	fo(i,0,K-1)
    	{
    		fo(j,0,K-1)
    		if (i|j)
    		{
    			k=j;
    			while (k<K)
    			k+=max(i,k);
    			
    			f[2][i][j]=k%K;
    		}
    	}
    	fo(i,2,n-1)
    	{
    		fo(j,0,K-1)
    		{
    			fo(k,0,K-1)
    			if (j|k)
    			{
    				l=k;
    				
    				fo(I,0,K-1)
    				if (f[i][max(j,I)][l]>-1)
    				l=f[i][max(j,I)][l];
    				else
    				break;
    				
    				if (I==K)
    				f[i+1][j][k]=l;
    			}
    		}
    	}
    	
    	fo(j,0,K-1)
    	{
    		fo(l,0,K-1)
    		if (j|l)
    		{
    			A=l;
    			while (A<K)
    			{
    				g[1][j][A][l]=A;
    				A+=max(j,A);
    			}
    		}
    	}
    	fo(i,2,n)
    	{
    		fo(j,0,K-1)
    		{
    			fo(l,0,K-1)
    			if (j|l)
    			{
    				A=l;
    				
    				fo(k,0,K-1)
    				if (A>-1)
    				{
    					g[i][j][k][l]=A;
    					A=f[i][max(j,k)][A];
    				}
    				else
    				break;
    			}
    		}
    	}
    	
    	fo(i,1,n)
    	dp[0][i][0][1]=1;
    	
    	N=0;
    	dfs(0,1);
    	Dfs(0,1);
    	
    	printf("%lld
    ",(ans+mod)%mod);
    	
    	fclose(stdin);
    	fclose(stdout);
    	
    	return 0;
    }
    
  • 相关阅读:
    动手实现 Redux(六):Redux 总结
    动手实现 Redux(五):不要问为什么的 reducer
    动手实现 Redux(四):共享结构的对象提高性能
    动手实现 Redux(三):纯函数(Pure Function)简介
    动手实现 Redux(二):抽离 store 和监控数据变化
    动手实现 Redux(一):优雅地修改共享状态
    React.js 的 context
    高阶组件(Higher-Order Components)
    实战分析:评论功能(六)
    实战分析:评论功能(五)
  • 原文地址:https://www.cnblogs.com/gmh77/p/11716770.html
Copyright © 2011-2022 走看看