• 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
    */
    
  • 相关阅读:
    centos7系统修改内核
    使用yum update更新文件系统时不更新内核的方法
    实现让用户不断的猜年龄,但只给最多3次机会,超过次数猜不对就退出程序。
    yum安装软件中的y/d/N
    MySQL5.7.15数据库配置主从服务器实现双机热备实例教程
    CentOS7.2 多个python版本共存
    CentOS 7.2 安装Python3.5.2
    R语言与概率统计(五) 聚类分析
    R语言与概率统计(四) 判别分析(分类)
    R语言与概率统计(三) 多元统计分析(下)广义线性回归
  • 原文地址:https://www.cnblogs.com/beiyuoi/p/6337648.html
Copyright © 2020-2023  润新知