codeforces J. Straight Master 2017EC final J 思维+差分

链接:http://codeforces.com/gym/101775/problem/J

思路:https://www.jianshu.com/p/83ea421664fb

对于 差分完的数组B 其实如果 bi >0 表示可以在i位置打出去bi个顺子并且i作为顺子的第一张牌,  如果bi <0 表示必须在将 i-1

 位置当做末尾并且打出去 abs(bi) 次顺子。

那么就树状数组维护一下子。

代码:

#include<bits/stdc++.h>

using namespace std;
typedef long long ll;
const int N = 2e5+5;
ll c[N];
ll a[N];
ll b[N];
int n;

int lowbit(int x)
{
    return x&(-x);
}

void update(int x,ll val)
{
    for(;x<=n+2;x+=lowbit(x))
    {
        c[x]+=val;
    }
}

ll query(int x)
{
    ll sum=0;
    for(;x>0;x-=lowbit(x))
    {
        sum+=c[x];
    }
    return sum;
}

int main()
{
    int T;
    scanf("%d",&T);
    int kk=0;
    while(T--)
    {
        scanf("%d",&n);
        a[0]=a[n+1]=0;
        for(int i=0;i<=n+5;i++) c[i]=0;
        for(int i=1;i<=n;i++){
            scanf("%lld",&a[i]);
        }

        for(int i=1;i<=n+1;i++) b[i]=a[i]-a[i-1];
        /*
        for(int i=1;i<=n+1;i++) cout<<b[i]<<" ";
        cout<<endl;
        */
        ll sum=0;
        int f=0;
        for(int i=1;i<=n+1;i++)
        {
            if(b[i]==0) continue;
            if(b[i]>0){
                update(i,b[i]);
            }
            else if(b[i]<0)
            {
                ll xx=query(i-3);
                xx-=sum;
                //cout<<"xx "<<xx<<endl;
                if(xx>=abs(b[i])){
                    sum+=abs(b[i]);
                    continue;
                }
                else{
                    f=1; break;
                }
            }
        }

        if(f) printf("Case #%d: No\n",++kk);
        else printf("Case #%d: Yes\n",++kk);

    }
    return 0;
}

/*

1
7
1 2 3 5 3 2 1


1
14
1 2 3 5 3 2 1 1 2 3 5 3 2 1

100
5
1 2 3 4 5
5
1 0 1 0 1

*/

猜你喜欢

转载自blog.csdn.net/yjt9299/article/details/82902166
今日推荐