zoukankan      html  css  js  c++  java
  • Atcoder Regular Contest 072 C Alice in linear land(思维题)

    Atcoder 题面传送门 & 洛谷题面传送门

    首先求出 \(s_i\) 表示经过 \(i\) 次操作后机器人会位于什么位置,显然 \(s_0=D\)\(s_i=\min(s_{i-1},|s_{i-1}-a_i|)\)

    考虑修改某个位置的 \(a_i\) 的本质是什么。注意到不论你将 \(a_i\) 改为什么值,最终的 \(s_i\) 一定在 \([0,s_{i-1}]\) 中,也就是说我们需求出是否 \(\exist v\in [0,s_{i-1}]\) 使得将 \(s_i\) 改为 \(v\) 后经过 \(i+1\sim n\)\(n-i\) 次操作,得到的值非零。

    考虑二元函数 \(f(v,a[1\dots n])\) 表示 \(v\) 经过 \(a_1,a_2,\dots,a_n\) 的作用下得到的值。那么题目转化为是否 \(\exist v\in [0,s_{i-1}]\) 使得 \(f(v,a[i+1\dots n])\neq 0\)。我们考虑分析这个 \(f\) 函数的性质,首先非常明显的一点是 \(\forall v,f(v,a[1\dots n])\leq f(v+1,a[1\dots n])\),证明异常容易,考虑序列 \(s_0=v,s_i=\min(s_{i-1},|s_{i-1}-a_i|)\),以及序列 \(s'_0=v+1,s'_i=\min(s'_{i-1},|s'_{i-1}-a_i|)\),随便归纳一下就可以得到 \(s_i\leq s'_i\),故 \(s_n\leq s'_n\)。另一个需要注意到的地方是这里 \(0\) 的特殊性,u1s1 感觉很多题目都要用到 \(0\) 这样特殊的数的性质解题(譬如 CF258E),这个地方连 ycx 神仙都没想到。注意到 \(\forall v\geq 0\)\(f(v,a[1\dots n])\geq 0\),而 \(f(0,a[1\dots n])=0\),再结合前一个性质可知满足 \(f(v,a[1\dots n])=0\) 是一个形如 \([0,g]\) 的区间,也就是说最小的满足 \(f(v,a[1\dots n])\neq 0\)\(v\)\(g+1\)

    这样一来思路就有了。考虑设 \(g_i\) 表示满足 \(f(v,a[i\dots n])\neq 0\) 的最小的 \(v\)。显然 \(g_{n+1}=1,g_i\geq g_{i+1}\),考虑递推求出 \(g_i\),对于某个 \(i\) 我们有 \(f(g,a[i\dots n])>0\Leftrightarrow f(\min(g-a_{i},g),a[i+1\dots n])>0\)。这样就可以分情况讨论了,若 \(|g_{i+1}-a_{i+1}|\ge g_{i+1}\),那么 \(g_{i}=g_{i+1}\) 就符合条件,否则 \(\min(g_i,|g_i-a_{i+1}|)=g_i-a_{i+1}\),而我们要使得 \(g_i-a_{i+1}\geq g_{i+1}\),故 \(g_i=a_{i+1}+g_{i+1}\)

    时间复杂度线性。

    #include <bits/stdc++.h>
    using namespace std;
    #define fi first
    #define se second
    #define fill0(a) memset(a,0,sizeof(a))
    #define fill1(a) memset(a,-1,sizeof(a))
    #define fillbig(a) memset(a,63,sizeof(a))
    #define pb push_back
    #define ppb pop_back
    #define mp make_pair
    template<typename T1,typename T2> void chkmin(T1 &x,T2 y){if(x>y) x=y;}
    template<typename T1,typename T2> void chkmax(T1 &x,T2 y){if(x<y) x=y;}
    typedef pair<int,int> pii;
    typedef long long ll;
    typedef unsigned int u32;
    typedef unsigned long long u64;
    namespace fastio{
    	#define FILE_SIZE 1<<23
    	char rbuf[FILE_SIZE],*p1=rbuf,*p2=rbuf,wbuf[FILE_SIZE],*p3=wbuf;
    	inline char getc(){return p1==p2&&(p2=(p1=rbuf)+fread(rbuf,1,FILE_SIZE,stdin),p1==p2)?-1:*p1++;}
    	inline void putc(char x){(*p3++=x);}
    	template<typename T> void read(T &x){
    		x=0;char c=getchar();T neg=0;
    		while(!isdigit(c)) neg|=!(c^'-'),c=getchar();
    		while(isdigit(c)) x=(x<<3)+(x<<1)+(c^48),c=getchar();
    		if(neg) x=(~x)+1;
    	}
    	template<typename T> void recursive_print(T x){if(!x) return;recursive_print(x/10);putc(x%10^48);}
    	template<typename T> void print(T x){if(!x) putc('0');if(x<0) putc('-'),x=~x+1;recursive_print(x);}
    	void print_final(){fwrite(wbuf,1,p3-wbuf,stdout);}
    }
    const int MAXN=5e5;
    int n,qu,a[MAXN+5],b[MAXN+5];
    int main(){
    	scanf("%d%d",&n,&a[0]);b[n+1]=1;
    	for(int i=1;i<=n;i++) scanf("%d",&a[i]);
    	for(int i=n;i;i--) b[i]=(b[i+1]<=a[i]/2)?b[i+1]:b[i+1]+a[i];
    	for(int i=1;i<=n;i++) a[i]=min(a[i-1],abs(a[i-1]-a[i]));
    	scanf("%d",&qu);while(qu--){int x;scanf("%d",&x);printf("%s\n",(a[x-1]>=b[x+1])?"YES":"NO");}
    	return 0;
    }
    
  • 相关阅读:
    (转+原)python中的浅拷贝和深拷贝
    (原)torch7中添加新的层
    (原+转)ubuntu终端输出彩色文字
    (原)torch中显示nn.Sequential()网络的详细情况
    (原)python中使用plt.show()时显示图像
    eclipse 注释模板
    leetcode 11 最大盛水容器
    leetcode 9 回文数字
    leetcode8 字符串转整数
    利用Intent启动activity的例子
  • 原文地址:https://www.cnblogs.com/ET2006/p/arc072c.html
Copyright © 2011-2022 走看看