zoukankan      html  css  js  c++  java
  • POI2011 MET-Meteors

    题目描述

    题解:

    第一道整体二分。

    如果只有一个询问,我们可以二分答案,然后O(n)验证;

    对于多种询问而且不强制在线,我们就可以使用整体二分。

    整体二分的精髓是,先想一个二分暴力,然后把所有二分过程放在一起。

    还有,整体二分中,分的是值域。

    对于本题直接二分值域,然后将前$mid$个操作扔到树状数组/线段树中。

    然后按能/不能完成二分。

    到达底层,值域为$[l,l]$,我们就可以直接赋值了。

    代码:

    #include<vector>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    #define N 300050
    #define ll long long
    const int inf = 0x3f3f3f3f;
    inline int rd()
    {
        int f = 1,c = 0;char ch=getchar();
        while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
        while(ch>='0'&&ch<='9'){c=10*c+ch-'0';ch=getchar();}
        return f*c;
    }
    int n,m,k;
    int ans[N],o[N];
    vector<int>ve[N];
    struct node
    {
        int id;
        ll lim;
    }p[N],tmpl[N],tmpr[N];
    int tim;
    struct BIT
    {
        ll f[N];
        void up(int x,ll d)
        {
            if(!x)return ;
            while(x<N)f[x]+=d,x+=(x&-x);
        }
        ll down(int x)
        {
            if(!x)return 0;
            ll ret = 0;
            while(x)ret+=f[x],x-=(x&-x);
            return ret;
        }
    }tr;
    struct Stars
    {
        int l,r,d;
    }s[N];
    void update(int l,int r,int d)
    {
        if(l<=r)
        {
            tr.up(l,d);
            tr.up(r+1,-d);
        }else
        {
            tr.up(1,d),tr.up(r+1,-d);
            tr.up(l,d),tr.up(m+1,-d);
        }
    }
    void divi(int l,int r,int beg,int ens)
    {
        if(beg>ens)return ;
        if(l==r)
        {
            for(int i=beg;i<=ens;i++)
                ans[p[i].id] = l;
            return ;
        }
        int mid = (l+r)>>1;
        while(tim<mid)tim++,update(s[tim].l,s[tim].r,s[tim].d);
        while(tim>mid)update(s[tim].l,s[tim].r,-s[tim].d),tim--;
        int lt=0,rt=0;
        for(int i=beg;i<=ens;i++)
        {
            ll sum = 0;
            for(int j=0;j<ve[p[i].id].size();j++)
            {
                sum+=tr.down(ve[p[i].id][j]);
                if(sum>=p[i].lim)break;
            }
            if(sum>=p[i].lim)tmpl[++lt]=p[i];
            else tmpr[++rt]=p[i];
        }
        for(int i=beg;i<=beg+lt-1;i++)p[i]=tmpl[i-beg+1];
        for(int i=beg+lt;i<=ens;i++)p[i]=tmpr[i-beg-lt+1];
        divi(l,mid,beg,beg+lt-1);
        divi(mid+1,r,beg+lt,ens);
    }
    int main()
    {
        n = rd(),m = rd();
        for(int i=1;i<=m;i++)
        {
            o[i] = rd();
            ve[o[i]].push_back(i);
        }
        for(int i=1;i<=n;i++)
        {
            p[i].id = i;
            p[i].lim = rd();
        }
        k = rd();
        for(int i=1;i<=k;i++)
            s[i].l = rd(),s[i].r = rd(),s[i].d = rd();
        divi(1,k+1,1,n);
        for(int i=1;i<=n;i++)
        {
            if(ans[i]==k+1)puts("NIE");
            else printf("%d
    ",ans[i]);
        }
        return 0;
    }
  • 相关阅读:
    linux下mysql基于mycat做主从复制和读写分离之基础篇
    HttpClient之基本使用
    查阅资料学习的书签(补充中.......)
    java架构《Socket网络编程基础篇》
    Redis常见配置文件详解
    redis学习教程五《管道、分区》
    redis学习教程四《管理、备份、客户端连接》
    js将json数组转成tree对象
    小程序转发事件生命周期
    mpvue开发小程序添加页面
  • 原文地址:https://www.cnblogs.com/LiGuanlin1124/p/10201406.html
Copyright © 2011-2022 走看看