card card card HDU - 6205( 思维 、不知道为什么线段树ME)

版权声明:欢迎大佬指正! https://blog.csdn.net/sinat_36215255/article/details/82192768

https://vjudge.net/problem/HDU-6205

题意略

当时队友秒出的思路是,保存一个前缀和,然后枚举每一位 i,查找 i 到 i+n-1 qu第一区,第一个前缀和小于当前前缀和的数。

然后开始写,跟多校那个题思路写法都一样。

结果ME了

我 ???,队友???

然后改小数组  ME

我??? 队友???

然后手动加栈 ME

我??? 队友???

然后另外一个队友重写线段树  ME

我??? 队友1??? 队友2 ???

队友2疯狂认为是return  inf 的问题,被我和队友1赶走。

放弃此题; to be continue...

最后半小时觉得再改改,改 ME

我 。。。    队友1 。。。

我换了思路,一想,发现对于 枚举每位 i ,找到它的可取区间的尾部 j 时,我们下次可以直接跳到尾部 j +1 开始为新的起点 i,因为从原位置 到尾部 i - j 这个区间都不会再有比原来值更优秀的解了。想到这不解释,直接写完交,还剩2min,wa了

我??。。。 队友12 (面无表情,习以为常);

后来发现,j的枚举范围错了,j应该枚举到 i + n -1 ,并且寻找尾部时,不一定是大于零,也有可能是i - j 长度为n取到整个区间。

改完,遂AC

L 题 end。。。

PS : 发现学弟学妹的H题过得那么多,过得我很懵,结果看了看他们的代码,被我hack掉了直接,,

     原来不是我们太菜学弟学妹太强,而是数据太水。。。。

代码如下:

#include <iostream>
#include <cstring>
#include <algorithm>
#include <cstdio>
#include <cmath>
#include <queue>
#include <vector>
#pragma comment(linker,"/STACK:1024000000,1024000000")
#define lson root*2,l,mid
#define rson root*2+1,mid+1,r
using namespace std;
const int inf = 0x3f3f3f3f;
const int maxn=2e6+100;
int sum[maxn*2];
int a[maxn];
int b[maxn];
int ans[maxn*2];
int main()
{
     int n;
     while(~scanf("%d",&n))
     {
         for(int i=1; i<=n; i++)
            scanf("%d",&a[i]);
           for(int i=1; i<=n; i++)
            scanf("%d",&b[i]);
        int N = 2*n;
        sum[0] = 0;
        ans[0] = 0;
        for(int i=1; i<=n; i++)
        {
            sum[i] = sum[i-1] + a[i]-b[i];
            ans[i] = ans[i-1] + a[i];
        }
         for(int i=1,j=n+1; i<=n;j++, i++)
        {
            sum[j] = sum[j-1] + a[i] - b[i];
            ans[j] = ans[j-1] + a[i];
        }
        int t = 0;
        long long res = 0;
        int d  = 0;
        for(int i=1; i<=n; i++)
        {
            for(int j=i; j<=n+i-1; j++)
            {
                if( sum[j] - sum[i-1] < 0)
                {
                    if(res < ans[j]-ans[i-1])
                    {
                         d = i-1;
                         res = ans[j]-ans[i-1];
                    }
                    i = j;
                    break;
                }
                if(j-i+1==n && res< ans[j]- ans[i-1])
                {
                    d = i - 1;
                     res = ans[j]- ans[i-1];
                     break;
                }
            }
        }
        printf("%d\n",d);
     }
    return 0;
}

附上傻逼 的ME代码。说不准某天就知道为啥ME了呢

#include <iostream>
#include <cstring>
#include <algorithm>
#include <cstdio>
#include <cmath>
#include <queue>
#include <vector>
#pragma comment(linker,"/STACK:1024000000,1024000000")
#define lson root*2,l,mid
#define rson root*2+1,mid+1,r
using namespace std;
const int inf = 0x3f3f3f3f;
const int maxn=1e6+5;
int sum[maxn*2];
int a[maxn];
int b[maxn];
int ans[maxn*2];
int mi[maxn*8];
void build(int root,int l,int r)
{
    if(l==r)
    {
        mi[root] = sum[l];
        return ;
    }
    int mid = (l+r)>>1;
    build(lson);
    build(rson);
    mi[root] = min(mi[root*2],mi[root*2+1]);
}
int dfs(int x,int l,int r,int rt)
{
    if(l==r)
    {
        return l;
    }
    int mid=(l+r)>>1;
    int zz=inf;
    if(mi[rt<<1]<x) zz=dfs(x,l,mid,rt<<1);
    else if(mi[rt<<1|1]<x) zz=dfs(x,mid+1,r,rt<<1|1);
    return zz;
}
int query(int x,int L,int R,int l,int r,int rt)
{
    if(L<=l&&r<=R)
    {
        if(mi[rt]<x)
        {
            return dfs(x,l,r,rt);
        }
        else return inf;
    }
    int mid=(l+r)>>1;
    int mini=inf;
    if(mi[rt*2]<x && L<=mid) mini=min(mini,query(x,L,R,l,mid,rt<<1));
    if(mini!=inf) return mini;
    if(mi[rt*2+1]<x && R>mid) mini=min(mini,query(x,L,R,mid+1,r,rt<<1|1));
    return mini;
}
int main()
{
     int n;
     while(~scanf("%d",&n))
     {
         for(int i=1; i<=n; i++)
            scanf("%d",&a[i]);
           for(int i=1; i<=n; i++)
            scanf("%d",&b[i]);
        int N = 2*n;
        sum[0] = 0;
        ans[0] = 0;
        for(int i=1; i<=n; i++)
        {
            sum[i] = sum[i-1] + a[i]-b[i];
            ans[i] = ans[i-1] + a[i];
        }
         for(int i=1,j=n+1; i<=n;j++, i++)
        {
            sum[j] = sum[j-1] + a[i]-b[i];
            ans[j] = ans[j-1] + a[i];
        }
        build(1,1,N);
        int res = 0;
        int dong = n;
        for(int i=1; i<=n; i++)
        {
            int cnt = sum[i] - sum[i-1];
            int t ;
            if(sum[i-1]==mi[1])
              t = i+n-1;
            else if(sum[i]-sum[i-1]<0)
                t = i;
            else
                t = query(sum[i-1],i,i+n-1,1,N,1);
            if(t==inf)
            {
               t = i+n-1;
            }
            if(t>maxn)
            {
                t = i+n-1;
            }
             if(ans[t]-ans[i-1]>res)
             {
                 dong =i-1;
                 res = max(res,ans[t]-ans[i-1]);
             }
             else if(ans[t]-ans[i-1]==res)
             {
                 dong = min(dong,i-1);
             }
        }
        printf("%d\n",dong);
     }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/sinat_36215255/article/details/82192768