• [BOI2011]MET-Meteors


    题目:洛谷P3527。

    题目大意:
    n个国家在某星球上建立了m个空间站(一个空间站只属于一个国家),空间站围成一个环。
    现在知道要下k天陨石,每天都在一个区间内下,每个点都下同样多的(若r>l,则说明区间是(1~r和l~m))。
    每个国家有一个目标陨石数。
    问每个国家最早在什么时候达到目标陨石数。若下完了还达不到,则输出NIE。
    解题思路:
    整体二分。
    对所有的国家一起二分,用树状数组维护前缀(后缀)。
    对于每个答案,将能达到目标的国家和达不到的国家分开,然后继续二分即可。
    时间复杂度(O(nlog^2 n))。

    线段树被卡常┭┮﹏┭┮

    C++ Code:

    #include<cstdio>
    #include<vector>
    #include<cctype>
    #define LoveLive long long
    const int M=500005,N=300005;
    int k,n,m,P[N],q[N],ans[N],now,tmp[N];std::vector<int>a[N];
    LoveLive Bit[M];
    bool type[N];
    inline int readint(){
        int c=getchar(),d=0;
        for(;!isdigit(c);c=getchar());
        for(;isdigit(c);c=getchar())
        d=(d<<3)+(d<<1)+(c^'0');
        return d;
    }
    struct stars{
        int l,r,s;
    }d[N];
    inline void add(int i,int a){for(;i<=m;i+=i&-i)Bit[i]+=a;}
    inline LoveLive query(int i){LoveLive a=0;for(;i;i-=i&-i)a+=Bit[i];return a;}
    inline void update(int tm,int det){
        if(d[tm].l<=d[tm].r)add(d[tm].l,det*d[tm].s),add(d[tm].r+1,-det*d[tm].s);else
        add(1,det*d[tm].s),add(d[tm].r+1,-det*d[tm].s),add(d[tm].l,det*d[tm].s);
    }
    void solve(int l,int r,int l1,int l2){
        if(l1>l2)return;
        if(l==r){
            for(int i=l1;i<=l2;++i)ans[q[i]]=l;
            return;
        }
        int mid=l+r>>1;
        while(now<mid)update(++now,1);
        while(now>mid)update(now--,-1);
        int cnt=0;
        for(int i=l1;i<=l2;++i){
            LoveLive p=0;
            int&id=q[i];
            for(int j=0,dd=a[id].size();j<dd&&p<P[id];++j)p+=query(a[id][j]);
            if(p>=P[id])type[id]=1,++cnt;else
            type[id]=0;
        }
        int t1=l1,t2=l1+cnt;
        for(int i=l1;i<=l2;++i)
        if(type[q[i]])tmp[t1++]=q[i];else
        tmp[t2++]=q[i];
        for(int i=l1;i<=l2;++i)q[i]=tmp[i];
        solve(l,mid,l1,t1-1);
        solve(mid+1,r,t1,l2);
    }
    int main(){
        n=readint(),m=readint();
        for(int i=1;i<=m;++i)a[readint()].push_back(i);
        for(int i=1;i<=n;++i)P[q[i]=i]=readint();
        k=readint()+1;
        for(int i=1;i<k;++i){
            d[i].l=readint();
            d[i].r=readint();
            d[i].s=readint();
        }
        d[k]=(stars){1,m,1e9};
        solve(1,k,1,n);
        for(int i=1;i<=n;++i)
        if(ans[i]<k)printf("%d
    ",ans[i]);else puts("NIE");
        return 0;
    }
    
  • 相关阅读:
    数学建模反思
    [Leetcode]unique binary search trees
    暑假结束了,开始新的学习
    什么是lamda表达式?
    [Java]三大特性之封装
    [Leetcode]003. Longest Substring Without Repeating Characters
    [Leetcode] 002. Add Two Numbers
    [Leetcode] 001.Two Sum
    [数据结构]AVL树
    [数据结构]二叉搜索树
  • 原文地址:https://www.cnblogs.com/Mrsrz/p/9291210.html
Copyright © 2020-2023  润新知