首页 > 其他分享 >CF1500F Cupboards Jumps 题解

CF1500F Cupboards Jumps 题解

时间:2023-12-13 17:13:02浏览次数:27  
标签:le tag2 题解 Jumps single ch CF1500F ri 翻转

题目链接

点击打开链接

题目解法

感觉是一个融合了许多技巧的题,很巧妙

题目要求 \(\max(h_i,h_{i+1},h_{i+2})-\min(h_i,h_{i+1},h_{i+2})=w_i\),这可以转化成另一个只和两项有关的形式为:\(\max(|h_i-h_{i+1}|,|h_i-h_{i+2}|,|h_{i+1}-h_{i+2}|)=w_i\)
令 \(d_i=h_{i+1}-h_i\),所以限制为 \(\max(|d_i|,|d_{i+1}|,|d_i+d_{i+1}|)=w_i\)
这是这道题的第一个巧妙之处:转成差分序列

考虑一个朴素的 \(dp\) 做法,令 \(f_{i,j}\) 为 \(|d_i|=j\),且满足前 \(i-1\) 个限制是否可行(注意,这里是 \(|b_i|\))
转移比较简单:

  1. \(f_{i,j}\to f_{i+1,w_i}(0\le j\le w_i)\)
  2. \(f_{i,w_i}\to f_{i+1,j}(0\le j\le w_i)\)
  3. \(f_{i,j}\to f_{i+1,w_i-j}(0\le j\le w_i)\)

为什么前 2 种情况不需要考虑 \(|d_i+d_{i+1}|\) 会不会 \(>w_i\),因为 \(d_i\le w_i,\;d_{i+1}\le w_i\),那么一定可以通过后面的调整符号从而使 \(d_i+d_{i+1}\le w_i\)

接下来是这道题的第二个巧妙之处:在 1 的形态上进行考虑
考虑 \(f\) 值为 1 的连续段的变化,可以发现,2 操作会使所有区间合并成 \([0,w_i]\),操作 1 会增加一个单点,操作 3 只是按照 \(\frac{w_i}{2}\) 翻转,不会改变单点和区间个数
所以,可以得到一个局面下,1 的连续段为至多一个区间和 \(O(n)\) 个单点

考虑维护区间和单点的变化
操作 1 和 2 是好维护的
操作 3 需要按照 \(\frac{w_i}{2}\) 翻转,手玩一下发现一个神奇的结论是:按照 \(\frac{w_i}{2}\) 翻转 等价于 按照 \(0\) 翻转,然后再往右平移 \(w_i\),这里是第三个巧妙之处
这样就好维护了,只需要记录当前是正的还是反的,以及平移的距离
这样可判断 YES OR NO

考虑构造方案
可以得到一个贪心的想法是,\(d_{n-1}\) 随便一个 1 位置,从后往前构造 \(d_i\)
如果 \(d_{i+1}=w_i\),则 \(d_i\) 为随便一个可行的位置,如果 \(d_i\) 可以为 \(w_i\),则 \(d_i=w_i\),否则 \(d_i=w_i-d_{i+1}\)
但这样只确定了 \(|d_i|\),我们需要定正负性,这个从后往前,如果我们不需要 \(|d_i+d_{i+1}|=w_i\),那么就使 \(d_i\) 和 \(d_{i+1}\) 异号

时间复杂度 \(O(n\log n)\)

#include <bits/stdc++.h>
#define F(i,x,y) for(int i=(x);i<=(y);i++)
#define DF(i,x,y) for(int i=(x);i>=(y);i--)
#define ms(x,y) memset(x,y,sizeof(x))
#define SZ(x) (int)x.size()-1
#define pb push_back
using namespace std;
typedef long long LL;
typedef unsigned long long ull;
typedef pair<int,int> pii;
template<typename T> void chkmax(T &x,T y){ x=max(x,y);}
template<typename T> void chkmin(T &x,T y){ x=min(x,y);}
template<typename T> void read(T &FF){
    FF=0;int RR=1;char ch=getchar();
    for(;!isdigit(ch);ch=getchar()) if(ch=='-') RR=-1;
    for(;isdigit(ch);ch=getchar()) FF=(FF<<1)+(FF<<3)+ch-48;
    FF*=RR;
}
const int N=1000100;
const LL inf=1e18;
int n;
LL C,w[N],d[N],ps[N],ans[N];
set<LL> single;
int main(){
    read(n),read(C);
    F(i,1,n-2) read(w[i]);
    //按w_i/2翻转 等价于  按原点翻转,在往右平移a_i
    LL l=0,r=C,tag2=0;//翻转之后需要平移的距离
    bool tag1=0;//是否需要以原点为中心翻转
    F(i,1,n-2){
        LL le,ri,ed;
        if(tag1) le=-w[i]+tag2,ri=tag2,ed=-w[i]+tag2;
        else le=-tag2,ri=w[i]-tag2,ed=w[i]-tag2;
        chkmax(l,le),chkmin(r,ri);
        while(!single.empty()&&(*single.begin())<le) single.erase(*single.begin());
        while(!single.empty()&&(*single.rbegin())>ri) single.erase(*single.rbegin());
        if(l>r&&single.empty()){ puts("NO");exit(0);}
        if((l<=ed&&ed<=r)||single.find(ed)!=single.end()){//f[i-1][w_i]=1
            single.clear(),tag1=0,tag2=0;
            l=0,r=w[i],ps[i]=w[i];continue;
        }
        //find one possible sol
        if(l<=r){
            if(tag1) ps[i]=-l+tag2;
            else ps[i]=l+tag2;
        }
        else{
            if(tag1) ps[i]=-(*single.begin())+tag2;
            else ps[i]=(*single.begin())+tag2;
        }
        tag1^=1,tag2=w[i]-tag2;
        if(tag1) single.insert(tag2-w[i]);
        else single.insert(w[i]-tag2);
    }
    puts("YES");
    if(l<=r) d[n-1]=tag1*(-1)*l+tag2;
    else d[n-1]=tag1*(-1)*(*single.begin())+tag2;
    // F(i,1,n-2) cout<<ps[i]<<' ';cout<<'\n';
    DF(i,n-2,1){
        if(w[i]==d[i+1]) d[i]=ps[i];
        else if(w[i]==ps[i]) d[i]=w[i];
        else d[i]=w[i]-d[i+1];
    }
    // F(i,1,n-1) cout<<d[i]<<' ';cout<<'\n';
    int neg=1;
    DF(i,n-2,1){
        if(abs(d[i])+abs(d[i+1])!=w[i]) neg*=-1;
        d[i]*=neg;
    }
    // F(i,1,n-1) cout<<d[i]<<' ';cout<<'\n';
    // F(i,1,n-2) assert(max(abs(d[i]),max(abs(d[i+1]),abs(d[i]+d[i+1])))==w[i]);
    ans[1]=0;
    F(i,1,n-1) ans[i+1]=ans[i]+d[i];
    LL mn=inf;
    F(i,1,n) chkmin(mn,ans[i]);
    F(i,1,n) ans[i]-=mn;
    F(i,1,n) printf("%lld ",ans[i]);puts("");
    fprintf(stderr,"%d ms\n",int(1e3*clock()/CLOCKS_PER_SEC));
    return 0;
}

标签:le,tag2,题解,Jumps,single,ch,CF1500F,ri,翻转
From: https://www.cnblogs.com/Farmer-djx/p/17899473.html

相关文章

  • springboot-micrometer潜在oom问题解决办法
    在服务中起一个监听Prometheus拉取的线程,在拉取完成之后清理调meterMap中内容比较多的tag,我这边是清理调gateway.requests.代码如下:@ComponentpublicclassPrometheusMeterRegistryFactory{@ResourceprivatePrometheusMeterRegistryprometheusMeterRegistry;......
  • CTFpwnAD世界pwnstack题解及栈溢出两种解法
    问题的出现这题我刚看到时差点没笑出来,但是尝试了一次之后我就笑不出来了。这题给了back_door后门函数,但是如果直接覆盖返回到后门函数起始位置会出现栈溢出问题。到这一步都没有出现问题,而继续ni的话就会卡住。基本上这里看到xmm0就是栈对其问题了。出现问题原因很简单,linux系统一......
  • 【洛谷 P1271】【深基9.例1】选举学生会 题解(计数排序)
    【深基9.例1】选举学生会题目描述学校正在选举学生会成员,有名候选人,每名候选人编号分别从1到,现在收集到了张选票,每张选票都写了一个候选人编号。现在想把这些堆积如山的选票按照投票数字从小到大排序。输入格式输入和以及个选票上的数字。输出格式求出排序后的选票编......
  • CTFpwnAD世界dice_game题解wp
    惯例checksec一下看看main首先seed函数用时间生成一个随机数,这个随机数做为srand函数的参数让srand函数生成一个种子。(这个种子会影响后面的rand函数生成结果,并且同样的种子会使rand函数生成同样的随机数,就是所谓的伪随机)以及看到这里会有连续五十轮游戏。sub_A20这里就是每一轮......
  • [ARC106F] Figures 题解
    题目链接点击打开链接题目解法这么神仙的推式子题看到生成树计数,第一反应是\(prufer\)序列考虑在\(prufer\)序列上搞这个东西可以得到\(ans=\sum\limits_{\sum\limits_{i=1}^nd_i=n-2}\binom{n-2}{d_1,d_2,...,d_n}\times\proda_i^{\underline{d_i+1}}\)考虑拆式子......
  • 问题解决
    howtomeasuressolutionsaddresstheimportanceofspeaking abilityandhowtodevelopit.Astherapid developmentofglobalization,itisofgreatnecessityforyoungstertoimproveourspeakingability.Howtoaddressthisproblem?Thefollowingsoluti......
  • AtCoder Beginner Contest 332 题解
    A-OnlineShopping题目链接AtcoderLuogu简要题意共有\(n\)件商品,第\(i\)件商品的价格为\(p_i\)日元,数量为\(q_i\)件。除了购买商品所需的的钱数,还要支付运费:如果所买商品的总价小于\(s\)日元,那么要支付运费\(k\)日元。问所需要的钱数是多少。简要思路模拟......
  • cdr 小问题解决方案
    1,插件卸载不干净1.1:插件自带的卸载1.2:点击cdr文件夹,选择路径CorelDRAWGraphicsSuiteX8\Draw\plugins64,删除其中所有的"*.cpg"文件(如果你安装了其他插件,这里也会有其他插件的cpg文件,请仔细辨认。或者直接全部删了,到时再安装一下你需要保留的插件)。 2,cdr矩形,对象属性无法更......
  • 【POJ 2418】Hardwood Species 题解(映射)
    描述阔叶树是一种植物群,具有宽阔的叶子,结出果实或坚果,通常在冬天休眠。美国的温带气候造就了数百种阔叶树种的森林,这些树种具有某些生物特征。例如,虽然橡树、枫树和樱桃都是硬木树,但它们是不同的物种。所有硬木树种加起来占美国树木的40%。另一方面,软木,或针叶树,从拉丁语的意思是......
  • luogu P9753题解
    题意描述有一个字符串,请你求出有多少个字串可以经过若干次,使它变成空串其中每次操作可以从字符串中删除两个相邻的相同字符,操作后剩余字符串会拼接在一起。##思路1可以枚举左端点,再枚举右端点,一边枚举一边判断是否合法时间复杂度$O(n^2)$空间复杂度$O(n)$##思......