2019.10.07题解

有点遗憾,T2题理解错了爆了45分,T3打的正解忘记是long long内存炸掉了。

 

T1

首先可以用1.3s左右筛出1e7个质数,之后我们发现每次区间移动只会改变2个值,所以可以用两个指针记录中位数,每次的移动可以看成常数级的。

ps:bitset真玄学,cbx因为用bitset CE了(不加万能库就没事)。而且bitset很吃O2,不开跑9s,开了跑进2s

 

T2

我们发现每次加入一个点之后要么拿掉它,要么以后拿这次拿集合的最大值,无论怎样集合的最大值不会变大,所以考虑用一个单调指针维护最大值的位置,复杂度$ O(nk) $

 

T3

正解挂分系列,给每个点开8个200大小的tmp数组,内存用int算的,打完调完才发现是long long,其实还是考试心态不行,先把子树全dfs一遍再去更新答案的思路应该是挺好想到的,但是当时就是太慌了。

我的思路:

设dp[0/1][i][j]为到i点从上到下/从下到上用了j次面包的最大收益。

首先考虑子树的合并:(懒得写了,直接上代码吧)

 

   for(int j=0;j<=m;j++)
  {
         f[0][j]=max(f[0][j],dp[0][y][j]),g[0][j]=max(g[0][max(0ll,j-1)],f[0][j]);
         f[1][j]=max(f[1][j],dp[1][y][j]),g[1][j]=max(g[1][max(0ll,j-1)],f[1][j]);
         d[0][j]=max(d[0][j],dp[0][y][j]-p[y]),h[0][j]=max(h[0][max(0ll,j-1)],d[0][j]);
         d[1][j]=max(d[1][j],dp[1][y][j]-p[y]),h[1][j]=max(h[1][max(0ll,j-1)],d[1][j]);
   }

 

再以x点为lca更新ans

                for(int j=0;j<=m;j++)
                {
                        ans=max(ans,g[0][m-j]+dp[1][y][j]);
                        ans=max(ans,g[1][m-j]+dp[0][y][j]);
                        if(j!=m) ans=max(ans,g[0][m-j-1]+dp[1][y][j]+s[x]-p[y]);
                        if(j!=m) ans=max(ans,h[1][m-j-1]+dp[0][y][j]+s[x]);
                }

最后把子树传给x

        for(int j=0;j<=m;j++) 
        {
                dp[0][x][j]=max(0ll,f[0][j]);
                if(j) dp[0][x][j]=max(dp[0][x][j],f[0][j-1]+s[x]-p[fa]);
                dp[1][x][j]=max(0ll,f[1][j]);
                if(j) dp[1][x][j]=max(dp[1][x][j],d[1][j-1]+s[x]);
                ans=max(ans,dp[0][x][j]);
                ans=max(ans,dp[1][x][j]);
        }

 

posted @ 2019-10-07 18:01  ATHOSD  阅读(130)  评论(3编辑  收藏  举报