zoukankan      html  css  js  c++  java
  • E. Alice and the Unfair Game 统计方案 #593 (Div. 2)

    题意: 

    有n个盒子  一个小球 和m次猜测序列(a1-am)  

    小球一开始位于初始位置s 第一次猜测前可以移动一次小球(移动到相邻位置或者原地不动)然后每次猜测可以移动一次小球 所以最多移动m+1次

    问有多少对 s(起始位置) t(结束位置) 满足不被猜测到

    题解:

    • 显然可以观察出一个结论 对一小球的某一个初始位置 它所能到达的结束位置的集合里的所有元素是连续的 所以对于该起始位置有一个左界(向左最远能到达哪里) 和一个右界
    • 假设要求出左边界 按照贪心策略 小球只会进行两种操作 等待和左移 右边界同理
    • 所以这里可以得到一个$O(nm)$复杂度的算法  可惜过不得
    • 可以将其看作是一个 $m*n$ 的图  每行都会有一个障碍 位于 $(i,ai)$ , $(0,i)$表示第i个小球的起始位置  所以问题就转化为小球一开始处于第0行 可以向下向左下向右下移动  求出每个初始点的左右界
    • 设 L[i] 为向左移动过程中原地等待的次数
    • 从m~1倒着放入障碍  显然  当前障碍会影响起始点位于:ai+当前行数的小球(该小球一路左下移动 直到遇到该障碍不得不向下移动) 当他向下移所到达的点 完全等效于 起始点位于 ai+当前行数+1 的小球,  一路向左下移动到达的点 因为i+1~m的状态已经处理好了  所以直接继承即可  记得加一 也就是当前不得不向下移动一次
    • 因为倒着放入障碍 所以起始点+1的小球也是一定能到该位置的(1~i 的障碍还没填入  所以是一定能到的  而且是一路往左下到达)
    #include <bits/stdc++.h>
    using namespace std;
    const int N=3e5+100;
    const int T=1e5;
    #define ll long long
    int n,m,a[N],L[N],R[N];
    
    int main()
    {
        cin>>n>>m;
        if(n==1)return printf("0"),0;
        for(int i=1;i<=m;i++)scanf("%d",&a[i]);
        for(int i=m;i>=1;i--)
        {
            L[i+a[i]+T]=L[i+a[i]+1+T]+1;
            R[a[i]-i+T]=R[a[i]-i-1+T]+1;
        }
        ll ans=0;
        for(int i=1;i<=n;i++)
        {
            int l=max(1,i-(m+1)+L[i+T]);
            int r=min(n,i+(m+1)-R[i+T]);
            ans+=1ll*(r-l+1);
        }
        cout<<ans;
        return 0;
    }
    View Code
  • 相关阅读:
    GIT 基本语句
    SpringBoot查看哪些配置类自动生效
    LeetCode第一题 两数之和
    static{} java中的静态代码块
    mybatis引入mapper映射文件的4种方法(转)
    MySQL Charset/Collation(字符集/校对)(转)
    MySQL数据库的创建(详细)
    Eclipse出现Tomcat无法启动:Server Tomcat v8.5 Server at localhost failed to start问题
    判断一个int类型数字的奇偶性
    linux中安装erlang时使用make命令报错问题
  • 原文地址:https://www.cnblogs.com/bxd123/p/11699162.html
Copyright © 2011-2022 走看看