zoukankan      html  css  js  c++  java
  • 繁华模拟赛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);
  • 相关阅读:
    pycharm设置linux中的python解析器进行本地开发
    linux安装python
    Jenkins自动构建的几种方式
    接口加密
    python接口自动化—unittest 常用的断言方法
    cookie 组成结构
    post请求的四种数据格式
    jmeter之数据库相关
    jmeter函数简介
    java_第一年_JDBC(6)
  • 原文地址:https://www.cnblogs.com/hyfer/p/5982176.html
Copyright © 2011-2022 走看看