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
  • 相关阅读:
    返回图片宽高比
    3.1/3.2图片上传类
    php获取图片的拍摄及其他数据信息
    上传类
    pathinfo()的用法
    上传并压缩图片
    将数组转化为键值对
    css3判断某个li标签
    禁止滚动条/启用滚动条
    Keepalived + haproxy双机高可用方案
  • 原文地址:https://www.cnblogs.com/bxd123/p/11699162.html
Copyright © 2011-2022 走看看