zoukankan      html  css  js  c++  java
  • BZOJ 2527: [Poi2011]Meteors

    Description

    (n)个国家一共有(m)个收集器,每次会在一个范围内落下(a_i)个物品,每个国家有收集目标,问每个国家至少多少次可以收集完.(n,m,k leqslant 3 imes 10^5)

    Solution

    整体二分.

    二分答案的同时将询问分类,分成小于等于(mid),和大于(mid),递归操作.

    用树状数组差分可以得到单点的权值,因为每层只会进行(n)次操作,一共(logn)层,所以总复杂度应该是(O(nlog^2n))

    Code

    /**************************************************************
        Problem: 2527
        User: BeiYu
        Language: C++
        Result: Accepted
        Time:22716 ms
        Memory:21396 kb
    ****************************************************************/
     
    #include <bits/stdc++.h>
    using namespace std;
     
    #define debug(a) cout<<#a<<"="<<a<<" "
    #define mid ((l+r)>>1)
     
    typedef long long LL;
    typedef pair< int,int > pr;
    const int N = 3e5+50;
    const int INF = 1e9+7;
     
    inline int in(int x=0,char ch=getchar()) { while(ch>'9' || ch<'0') ch=getchar();
        while(ch>='0' && ch<='9') x=x*10+ch-'0',ch=getchar();return x; }
     
    int n,m,k;
    int a[N],tar[N],t1[N],t2[N],tt[N],ans[N];
    vector< int > g[N];
    struct Q { int l,r,a; } qr[N];
     
    LL d[N];
    void Add(int x,LL v) { for(;x<=m;x+=x&-x) d[x]+=v; }
    LL Sum(int x,LL r=0) { for(;x;x-=x&-x) r+=d[x];return r; }
     
    void Solve(int l,int r,int L,int R) {
    //  debug(l),debug(r),debug(L),debug(R)<<endl;
    //  for(int i=L;i<=R;i++) cout<<a[i]<<" ";cout<<endl;
    //  cout<<"----------------------------------------"<<endl;
         
         
        if(l==r) {
            for(int i=L;i<=R;i++) ans[a[i]]=l;
            return;
        }
    //  if(l==1 && r==k) for(int i=1;i<=m;i++) cout<<Sum(i)<<endl;
        for(int i=l;i<=mid;i++) {
            if(qr[i].l<=qr[i].r) Add(qr[i].l,qr[i].a),Add(qr[i].r+1,-qr[i].a);
            else Add(1,qr[i].a),Add(qr[i].r+1,-qr[i].a),Add(qr[i].l,qr[i].a);
        }
    //  if(l==1 && r==k) for(int i=1;i<=m;i++) cout<<Sum(i)<<endl;
        int c1,c2;c1=c2=0;
        for(int i=L;i<=R;i++) {
            LL tmp=0;
            for(int j=0;j<(int)g[a[i]].size();j++) { tmp+=Sum(g[a[i]][j]);if(tmp>=tar[a[i]]) break; }
            if(tmp>=tar[a[i]]) t1[++c1]=a[i];
            else t2[++c2]=a[i];
    //      cout<<a[i]<<" "<<tmp<<endl;
        }
    //  debug(c1),debug(c2)<<endl;
    //  cout<<"----------------------------------------"<<endl;
        for(int i=1;i<=c2;i++) a[L+c1+i-1]=t2[i];
        for(int i=1;i<=c1;i++) a[L+i-1]=t1[i];
        Solve(mid+1,r,L+c1,R);
         
        for(int i=l;i<=mid;i++) {
            if(qr[i].l<=qr[i].r) Add(qr[i].l,-qr[i].a),Add(qr[i].r+1,qr[i].a);
            else Add(1,-qr[i].a),Add(qr[i].r+1,qr[i].a),Add(qr[i].l,-qr[i].a);
        }
        Solve(l,mid,L,L+c1-1);
    }
     
    int main() {
    //  freopen("in.in","r",stdin);
        n=in(),m=in();
        for(int i=1,x;i<=m;i++) x=in(),g[x].push_back(i);
        for(int i=1;i<=n;i++) tar[i]=in(),a[i]=i;
        k=in();
        for(int i=1;i<=k;i++) {
            int ll=in(),rr=in(),aa=in();
            qr[i]=(Q){ ll,rr,aa };
        }
        qr[++k]=(Q){ 1,m,INF };
        Solve(1,k,1,n);
        for(int i=1;i<=n;i++) (ans[i]==k)?puts("NIE"):printf("%d
    ",ans[i]);
        return 0;
    }
    /*
    3 5
    1 3 2 1 3
    10 5 7
    3
    4 2 4
    1 3 1
    3 5 2
    */
    
  • 相关阅读:
    html 输入框 只能输入数字 只能输入字母数字 等组合
    element中table高度自适应问题
    设置千分位问题(改变数据结构形式--转成字符串)
    在element的table接受数据设置千分位问题(不改变数据类型)
    element在使用tab页时,echarts只在第一个页面加载(第二个tab页也在默认tab页显示)问题
    css1
    B/S(Web)实时通讯解决方案
    WebRTC介绍及简单应用
    webpack的编译流程
    01 写一个 mySetInterVal(fn, a, b),每次间隔 a,a+b,a+2b 的时间,然后写一个 myClear,停止上面的 mySetInterVal
  • 原文地址:https://www.cnblogs.com/beiyuoi/p/6337648.html
Copyright © 2011-2022 走看看