首页 > 其他分享 >[ABC221G] Jumping sequence

[ABC221G] Jumping sequence

时间:2024-09-05 23:35:40浏览次数:10  
标签:sequence int sum mid 2010 leq Jumping ABC221G 转移

My Blogs

[ABC221G] Jumping sequence

做法有点深刻,优化方式非常深刻。

首先是哈密顿距离和切比雪夫距离的转化:把坐标系旋转四十五度,变成每次向左上,右上,左下,右下走 \(\sqrt 2 a_i\) 的距离,要求最后走到 \((A+B,A-B)\)。然后这样可以对于横纵坐标分开做了(非常神奇)。

问题转化成了询问是否存在序列 \(x\) 满足 \(\forall i,x_i\in\{-1,1\},A=\sum x_ia_i\)。先钦定全都是 \(+1\) 或者 \(-1\) 之后可以变形为,询问是否能从 \(a\) 中选择若干个数使得和为 \(A\)。可以直接 bitset 做到 \(\mathcal O(\frac{nV^2}{w})\),但是存在更优秀的做法。

首先从前向后找到最大的 \(mid\) 满足 \(\sum_{j\leq mid}a_j\leq A\)。然后如果存在解,则一定是前面删掉若干个元素然后后面再加进来若干个元素。可以设 \(f_{l,r,i}\) 表示从 \([l,mid]\) 中选择一些负数,\([mid+1,r]\) 中选择一些正数,能否凑出来 \(i\)。

一个关键性质是 \(i\) 只需要保留 \([-V,V]\) 的部分,其中 \(V\) 是题目中数列的值域。证明比较简单,对于一种方案,假设选取的左侧负数是 \(x_1\dots x_k\),右侧选取的正数是 \(y_1\dots y_s\),如果当前 \(i\) 是正的就在左边加负数,否则在右边加正数。如果有一个序列取空了剩下的就直接全取了。因为 \(A-\sum_{j\leq mid}a_j\leq V\),所以上面这样值域不会超过 \([-V,V]\)。

但是 \(f\) 的状态就是 \(\mathcal O(nV^2)\) 的。注意到如果固定了 \(i,r\),合法的 \(l\) 是一段前缀。可以记录 \(g_{i,j}\) 表示当前右端点是 \(i\),值是 \(j\),合法的最大左端点是 \(g_{i,j}\)。转移:

\[\begin{aligned} g_{i+1,j}&\leftarrow g_{i,j}\\ g_{i+1,j+a_i}&\leftarrow g_{i,j}\\ g_{i+1,j-a_k}&\leftarrow k\;\;\;\;\;\;\;\;\;\;\;\;\;\;k\leq g_{i+1,j} \end{aligned} \]

现在复杂度瓶颈在于第三种转移。但是可以发现许多第三种转移都是没用的:如果 \(k\leq g_{i,j}\),则可以在 \(i-1\) 的时候就转移掉这个 \(k\)。所以每次只需要转移新添进候选值的 \(k\),即 \(k\in(g_{i,j},g_{i+1,j}]\)。因为 \(g\) 单调不降,对于一个 \(j\),\(k\) 的枚举次数即为 \((\sum_{i}g_{i,j}-g_{i-1,j})\leq n\),所以这样总复杂度是 \(\mathcal O(nV)\)。输出方案也比较平凡,只需要记录从哪个状态转移过来的即可。

int n,A,B,a[2010],f[2010][4010];
pii from[2010][4010];
bitset<2010> v1,v2;
void solve(int X)
{
    if(X<0)puts("No"),exit(0);
    int v=0,I=0;memset(f,0,sizeof(f));
    while(I<n&&v+a[I+1]<=X)v+=a[++I];
    if(I==n&&v<X)puts("No"),exit(0);
    v=X-v,f[I][2000]=I+1,v1.reset();
    for(int i=I+1;i<=n;++i)
    {
        for(int j=4000;j>=0;--j)
        {
            if(Mmax(f[i][j],f[i-1][j]))from[i][j]=mp(i-1,j);
            if(j>a[i])if(Mmax(f[i][j],f[i-1][j-a[i]]))
            from[i][j]=mp(i-1,j-a[i]);
            for(int k=f[i-1][j];k<f[i][j];++k)if(j>=a[k])
            if(Mmax(f[i][j-a[k]],k))from[i][j-a[k]]=mp(i,j);
        }
    }
    if(!f[n][2000+v])puts("No"),exit(0);
    for(int i=1;i<=I;++i)v1[i]=1;
    int i=n,j=2000+v,x,y;
    while(i!=I||j!=2000)
    {
        x=from[i][j].fi,y=from[i][j].se;
        if(x==i)v1[f[i][j]]=0;
        else if(y!=j)v1[i]=1;
        i=x,j=y;
    }
}
inline void mian()
{
    read(n,A,B),A=A+B,B=A-B-B;
    for(int i=1;i<=n;++i)read(a[i]),A+=a[i],B+=a[i];
    if((A&1)||(B&1))return puts("No"),void();
    solve(A>>1),v2=v1,solve(B>>1),puts("Yes");
    for(int i=1;i<=n;++i)
    {
        if(v1[i]==v2[i]){if(v1[i])putchar('R');else putchar('L');}
        else{if(v2[i])putchar('U');else putchar('D');}
    }
}

标签:sequence,int,sum,mid,2010,leq,Jumping,ABC221G,转移
From: https://www.cnblogs.com/WrongAnswer90/p/18399404

相关文章

  • 浙大数据结构:01-复杂度2 Maximum Subsequence Sum
    数据结构MOOCPTA习题01-复杂度2MaximumSubsequenceSum#include<iostream>usingnamespacestd;constintM=100005;inta[M];intmain(){ intk; cin>>k; intf=1; for(inti=0;i<k;i++) { cin>>a[i]; if(a[i]>=0)//如......
  • CF 2001 D. Longest Max Min Subsequence(*1900) 思维
    CF2001D.LongestMaxMinSubsequence(*1900)思维题目链接题意:给你一个长度为\(n\)的序列\(a\),设\(S\)是\(a\)的所有可能的非空子序列的集合,且没有重复的元素。你的目标是找出\(S\)中最长的序列。如果有多个序列,请找出将奇数位置上的项乘以\(−1\)后,使词序最小......
  • 题解:AT_abc257_d [ABC257D] Jumping Takahashi 2
    [ABC257D]JumpingTakahashi2博客食用更佳:Myblog。大体思路这题是一道二分题,因为\(S\)越大,就越容易满足题目要求,\(S\)越小,就越难满足题目要求,符合二分的特点。下面先贴上二分代码。LLl=0,r=1e10;while(l<r){intmid=l+r>>1;if(check(mid))......
  • 题解:CF916B Jamie and Binary Sequence (changed after round)
    题意把一个数分解成恰好\(k\)个\(2^{a_i}\)次方的和,可以重复,要求保证最大的\(a_i\)要尽可能的小时,\(a\)的字典序尽可能大,输出序列\(a\)。分析首先我们借助二进制拆出一个满足\(n=\sum2^{a_i}\)序列\(a\),满足\(a\)的长度最小。若此时\(a\)的长度大于\(k\),显......
  • jumping sol.md
    首先,如果你做过BZ\(2144\)​,你可以发现一共只有:中间的往左跳。中间的往右跳。两边的往中间跳。第三个是对称的,我们不妨设他是\(fa\),前两个一个\(ls\),一个\(rs\)。那么我们有一棵二叉树,现在要问从一个点到另一个点方案数。两个点设为\(a,b\)。和\(2144\)不同的是,\(k......
  • 7.3 CANYONING TECHNIQUE:JUMPING
    7.3JUMPINGOVERVIEWTimetofly!Jumpingisoneofthemostfunthingswedoincanyoning.It’softenthereasonpeopleareattractedtothesportinitially,becauseofthehighthrillfactor.Butlet’srememberalthoughjumpingissuperfunfor......
  • Strings, Subsequences, Reversed Subsequences, Prefixes
    题目大意给定两个字符串s和t,求出在s里面有多少个本质不同的子序列,使得该序列的前缀包含t,且该序列的反串也包含t即s的子序列=t+x+反t‘首先要确定是否有,就是判断我的S字符串中有没有包含T字符串for(l=0;l<n;l++){ if(s[l]==t[num])num++; if(num==m)bre......
  • 题解:AT_abc367_c [ABC367C] Enumerate Sequences
    大致题意让你按照字典序输出一些长\(n\)的序列,序列中的数字有范围,且序列和需要为\(k\)。分析直接深搜。搜索的时候对从第一个元素开始,每个元素从小到大枚举所有可能的值,这样就保证答案按照字典序升序排列。用一个vector存储序列,到达边界之后计算一遍和,判断是否满足条件,然......
  • Atcoder [ABC367C] Enumerate Sequences 题解
    简要题意给定\(n,k\)和\(R_i\),你需要输出所有满足下列条件的整数序列:长度为\(n\)。第\(i\)个元素的范围为\([1,R_i]\)。一个序列的所有元素的总和为\(k\)的倍数。输出请按照按照从左至右按位从小到大的顺序输出。题解注意到数据范围很小,我们可以直接爆搜,这里用......
  • Padding Mask;Sequence Mask;为什么如果没有适当的掩码机制,解码器在生成某个位置的输出
    目录掩码Mask PaddingMask SequenceMask为什么需要SequenceMask?SequenceMask是如何工作的?具体实现为什么如果没有适当的掩码机制,解码器在生成某个位置的输出时,可能会“看到”并错误地利用该位置之后的信息自回归性质一、定义二、性质三、应用限制掩码Mask......