• 繁华模拟赛day8 牛栏


    /*
    标称并没有用到题解中提到的那种奇妙的性质,我们可以证明,正常从1开始走的话,需要T次,如何使这个次数减小?题解中提到一个办法,有一步小于n/t,我们考虑这一步,如果把它匀到左右两步中,则可以减小,就根据这个性质来优化
    next函数的部分,我当时用了一个倍增法,题解用了一个并查集,倍增比较直观,然而并查集更为巧妙
    */
    //my code
    #include<iostream>
    #include<cstdio>
    #include<string>
    #include<cstring>
    #include<algorithm>
    #include<vector>
    #include<queue>
    #define ll long long
    using namespace std;
    const int maxn = 600500;
    int n,q,cnt,ct[maxn];
    ll a[maxn],sum[maxn],ans;
    ll read(){
        char ch=getchar();
        ll x=0,f=1;
        while(!(ch>='0'&&ch<='9')){if(ch=='-')f=-1;ch=getchar();};
        while(ch>='0'&&ch<='9'){x=x*10+(ch-'0');ch=getchar();};
        return x*f;
    }
    ll greedy(int u,ll t){
        ll tot = 0,tmp = 0;
        ll j,lg,tst,nt;
        for(int i = 1;i <= n;i++){
            tmp++;
            if(a[u] + a[u+1] > t || i == n){
                
            }else{
                lg = 0;
                j = 1;
                tot = 0;
                while(lg>=0){
                    if(u+j<=n){
                        tst = sum[u+j]-sum[u-1];
                        nt = u + j;
                    }
                    else{
                        tst = sum[n] - sum[u-1] + sum[u+j-n];
                        nt = u + j - n;    
                    }
                    if(tot + tst <= t){
                        i += j;
                        tot += tst - a[nt];
                        u = nt;
                        lg++;
                        j <<= 1;
                    }else{
                        lg--;
                        j >>= 1;
                    }
                }
            }
            u++;
            if(u > n) u = 1;
            if(tmp >= ans) break;
        }
        return tmp;
    }
    void work(ll t){
        cnt = 0;
        ans = maxn;
        ct[++cnt] = 1;
        ll sum = a[1];
        for(int i = n;i > 1;i--){
            sum += a[i];
            if(sum > t) break;
            ct[++cnt] = i;
        }
        for(int i = 1;i <= cnt;i++){
            ans = min(ans,greedy(ct[i],t));
        }
        cout<<ans<<endl;
    }
    int main(){
        freopen("stall.in","r",stdin);
        freopen("stall.out","w",stdout);
        n = read();
        q = read();
        for(int i = 1;i <= n;i++){
            a[i] = read();
            sum[i] = sum[i-1] + a[i];
        }
        ll b;
        for(int i = 1;i <= q;i++){
            b = read();
            work(b);
        }
        return 0;
    }
    //std
    #include<cstdio>
    #include<iostream>
    #include<algorithm>
    #include<cstring>
    #include<cmath>
    #include<vector>
    #include<queue>
    #include<map>
    #include<set>
    #include<stack>
    #include<cstdlib>
    #include<string>
    #include<bitset>
    #define INF 1000000000
    #define N 2000005
    #define fi first
    #define se second
    #define debug(x) cout<<#x<<"="<<x<<endl
    #define MP(x,y) make_pair(x,y)
    using namespace std;
    typedef long long LL;
    typedef pair<int,int> pii;
    LL a[N],s[N];
    int to[N],fa[N],d[N];
    int findr(int x)
    {
        if(fa[x]==x)
            return x;
        else
        {
            int t=fa[x];
            fa[x]=findr(fa[x]);
            d[x]=d[x]+d[t];
            return fa[x];
        }
    }
    
    void Union(int x,int y)
    {
        fa[x]=y;
        d[x]=1;
    }
    
    int main()
    {
        int size = 256 << 20; // 256MB
        char *p = (char*)malloc(size) + size;
        __asm__("movl %0, %%esp
    " :: "r"(p));
        freopen("stall.in","r",stdin);
        freopen("stall.out","w",stdout);
        cin>>n>>q;
        for(i=1;i<=n;i++)
            scanf("%I64d",&a[i]),a[i+n]=a[i];
        for(i=n*2;i;i--)
            s[i]=s[i+1]+a[i];
        while(q--)
        {
            ans=INF;
            cin>>m;
            memset(d,0,sizeof(d));
            for(i=1;i<=n;i++)
                fa[i]=i,fa[i+n]=i+n;
            for(j=n*2,i=n*2;i;i--)
            {
                while(s[i]-s[j+1]>m) j--;
                to[i]=j+1;
                //debug(to[i]);
            }
            //if(q==1) return 0;
            for(i=1;i<=n;i++)
            {
                j=findr(i);
                while(to[j]<i+n)
                {
                    k=to[j];
                    Union(j,k);
                    j=findr(k);
                }
                findr(i);
                ans=min(ans,d[i]);
            }
            cout<<ans+1<<endl;
        }
        return 0;
    }
    // davidlee1999WTK 2015/
    // srO myk Orz
    //ios::sync_with_stdio(false);
  • 相关阅读:
    HYSBZ 3813 奇数国
    HYSBZ 4419 发微博
    HYSBZ 1079 着色方案
    HYSBZ 3506 排序机械臂
    HYSBZ 3224 Tyvj 1728 普通平衡树
    Unity 3D,地形属性
    nginx 的naginx 种包含include关键字
    Redis 出现NOAUTH Authentication required解决方案
    mysql 8.0出现 Public Key Retrieval is not allowed
    修改jar包里的源码时候需要注意的问题
  • 原文地址:https://www.cnblogs.com/hyfer/p/5982176.html
Copyright © 2020-2023  润新知