zoukankan      html  css  js  c++  java
  • BZOJ2527 & 洛谷3527:[Poi2011]Meteors——题解

    +++++++++++++++++++++++++++++++++++++++++++

    +本文作者:luyouqi233。               +

    +欢迎访问我的博客:http://www.cnblogs.com/luyouqi233/+

    +++++++++++++++++++++++++++++++++++++++++++

    https://www.luogu.org/problemnew/show/3527

    http://www.lydsy.com/JudgeOnline/problem.php?id=2527

    (事先说明,本人是开O2过的洛谷,如果不开的话请用数组模拟STL)

    (代码和题解参考洛谷的题解第一篇)

    (采用BZOJ翻译)

    Byteotian Interstellar Union有N个成员国。现在它发现了一颗新的星球,这颗星球的轨道被分为M份(第M份和第1份相邻),第i份上有第Ai个国家的太空站。这个星球经常会下陨石雨。
    BIU已经预测了接下来K场陨石雨的情况。BIU的第i个成员国希望能够收集Pi单位的陨石样本。你的任务是判断对于每个国家,它需要在第几次陨石雨之后,才能收集足够的陨石。
    输入:
    第一行是两个数N,M。
    第二行有M个数,第i个数Oi表示第i段轨道上有第Oi个国家的太空站。
    第三行有N个数,第i个数Pi表示第i个国家希望收集的陨石数量。
    第四行有一个数K,表示BIU预测了接下来的K场陨石雨。
    接下来K行,每行有三个数Li,Ri,Ai,表示第K场陨石雨的发生地点在从Li顺时针到Ri的区间中(如果Li<=Ri,就是Li,Li+1,...,Ri,否则就是Ri,Ri+1,...,m-1,m,1,...,Li),向区间中的每个太空站提供Ai单位的陨石样本。
    输出:
    N行。第i行的数Wi表示第i个国家在第Wi波陨石雨之后能够收集到足够的陨石样本。如果到第K波结束后仍然收集不到,输出NIE。
    数据范围: 
    1<=n,m,k<=3*10^5 1<=Pi<=10^9 1<=Ai<10^9

    显然是一道维护区间的题,如果不考虑用什么奇葩难写的数据结构的话,还是整体二分+树状数组好些。

    ……但是一旦会了整体二分之后不就是水题了吗……

    我们二分每个成员国最少需要多少波操作会到达他们的预定值,剩下的就是套路了。

    不过需要注意这题可能爆longlong,开longlong的同时记的判断并及时跳出。

    #include<algorithm>
    #include<iostream>
    #include<cstring>
    #include<cctype>
    #include<cstdio>
    #include<vector>
    #include<cmath>
    using namespace std;
    typedef long long ll;
    const int N=1000055;
    inline ll read(){
        ll X=0,w=0;char ch=0;
        while(!isdigit(ch)){w|=ch=='-';ch=getchar();}
        while(isdigit(ch))X=(X<<3)+(X<<1)+(ch^48),ch=getchar();
        return w?-X:X;
    }
    struct question{
        int l,r,op,id;
        ll k;
    }q[N],tmp1[N],tmp2[N];
    vector<int>g[N];
    int ans[N],aim[N];
    ll tree[N];
    int n,m,p;
    inline int lowbit(int t){return t&(-t);}
    inline void add(int x,ll y){//将a[x]+y
        for(int i=x;i<=m;i+=lowbit(i))tree[i]+=y;
    }
    inline ll query(int x){//1-x区间和
        ll res=0;
        for(int i=x;i>0;i-=lowbit(i))res+=tree[i];
        return res;
    }
    inline void modify(ll x,ll y,ll z){
        add(x,z);add(y+1,-z);
    }
    void solve(int L,int R,int l,int r){
        if(L>R)return;
        if(l==r){
            for(int i=L;i<=R;i++){
                if(q[i].op==1)ans[q[i].id]=l;
            }
            return;
        }
        int idx1=0,idx2=0,mid=(l+r)>>1;
        for(int i=L;i<=R;i++){
            if(q[i].op==1){
                ll tmp=0;
                for(int j=0;j<g[q[i].id].size();j++){
                    tmp+=query(g[q[i].id][j]);
                    if(tmp>q[i].k)break;
                }
                if(tmp>=q[i].k)tmp1[idx1++]=q[i];
                else{q[i].k-=tmp;tmp2[idx2++]=q[i];}
            }else{
                if(q[i].id<=mid){
                    if(q[i].op==2)modify(q[i].l,q[i].r,q[i].k);
                    else modify(q[i].l,m,q[i].k),modify(1,q[i].r,q[i].k);
                    tmp1[idx1++]=q[i];
                }else tmp2[idx2++]=q[i];
            }
        }
        for(int i=0;i<idx1;i++){
            question k=tmp1[i];
            if(k.op==2)modify(k.l,k.r,-k.k);
            else if(k.op==3)modify(k.l,m,-k.k),modify(1,k.r,-k.k);
        }
        bool ok1=0,ok2=0;
        int MID=L+idx1;
        for(int i=L;i<MID;i++)q[i]=tmp1[i-L],ok1=1;
        for(int i=MID;i<=R;i++)q[i]=tmp2[i-MID],ok2=1;
        if(ok1)solve(L,MID-1,l,mid);
        if(ok2)solve(MID,R,mid+1,r);
        return;
    }
    int main(){
        n=read(),m=read();
        for(int i=1;i<=m;i++)g[read()].push_back(i);
        for(int i=1;i<=n;i++)aim[i]=read();
        p=read();
        for(int i=1;i<=p;i++){
            q[i].l=read();q[i].r=read();q[i].k=read();
            if(q[i].r>=q[i].l)q[i].op=2;
            else q[i].op=3;
            q[i].id=i;
        }
        for(int i=1;i<=n;i++){
            q[i+p].k=aim[i];q[i+p].op=1;q[i+p].id=i;
        }
        solve(1,n+p,1,p+1);
        for(int i=1;i<=n;i++){
            if(ans[i]!=p+1)printf("%d
    ",ans[i]);
            else puts("NIE");
        }
        return 0;
    }
  • 相关阅读:
    Redis学习第二天
    Redis学习
    jQuery基础
    Hashtable 和 HashMap 的区别
    JSP页面乱码问题
    Day28 java8:Stream API
    转 链表中节点每k个一组反转
    day 27 lambda表达式(针对接口) & 函数式接口
    day20异常2
    day20 异常1
  • 原文地址:https://www.cnblogs.com/luyouqi233/p/8280709.html
Copyright © 2011-2022 走看看