zoukankan      html  css  js  c++  java
  • [Luogu P3527&BZOJ 2527][Poi2011]Meteors(整体二分+BIT)

    Description

    给定一个环,每个节点有一个所属国家,k次事件,每次对[l,r]区间上的每个点点权加上一个值,求每个国家最早多少次操作之后所有点的点权和能达到一个值

    Solution

    整体二分,维护一个区间修改单点查询的树状数组来统计mid次操作后每个国家收集到的陨石

    要判定最后也收集不够的国家,可以加一场1-m大小为INF的流星雨,如果ans==k+1输出"NIE"

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<cstdlib>
    #include<algorithm>
    #include<vector>
    #define INF 0x3f3f3f3f
    #define MAXN 300005
    using namespace std;
    typedef long long LL;
    int n,m,k,p[MAXN],id[MAXN],t[MAXN];
    int x[MAXN],y[MAXN],A[MAXN],ans[MAXN],T=0;
    LL c[MAXN];
    bool vis[MAXN];
    vector<int>a[MAXN];
    int read()
    {
        int x=0,f=1;char c=getchar();
        while(c<'0'||c>'9'){
            if(c=='-')f=-1;c=getchar();
        }
        while(c>='0'&&c<='9'){
            x=x*10+c-'0';c=getchar();
        }
        return x*f;
    }
    int lowbit(int x){return x&-x;}
    void add(int pos,int x)
    {
        while(pos<=m)
        c[pos]+=x,pos+=lowbit(pos);
    }
    LL query(int pos)
    {
        LL res=0;
        while(pos>0)
        res+=c[pos],pos-=lowbit(pos);
        return res;
    }
    void insert(int pos,int f)
    {
        if(x[pos]<=y[pos])
        add(x[pos],f*A[pos]),add(y[pos]+1,-f*A[pos]);
        else
        add(1,f*A[pos]),add(y[pos]+1,-f*A[pos]),add(x[pos],f*A[pos]);
    }
    void solve(int l,int r,int L,int R)
    {
        if(L>R)return; 
        if(l==r)
        {
            for(int i=L;i<=R;i++)ans[id[i]]=l;
            return;
        }
        int Mid=(l+r)>>1;
        while(T<Mid)++T,insert(T,1);
        while(T>Mid)insert(T,-1),--T;
        int cnt=0,idx;
        LL res;
        for(int i=L;i<=R;i++)
        {
            res=0,idx=id[i];
            for(int j=0;j<a[idx].size();j++)
            {
                res+=query(a[idx][j]);
                if(res>=p[idx])break;
            }
            if(res>=p[idx])vis[idx]=1,cnt++;
            else vis[idx]=0;
        }
        int j=L,k=L+cnt;
        for(int i=L;i<=R;i++)
        if(vis[id[i]])t[j++]=id[i];
        else t[k++]=id[i];
        for(int i=L;i<=R;i++)id[i]=t[i];
        solve(l,Mid,L,L+cnt-1);
        solve(Mid+1,r,L+cnt,R);
    }
    int main()
    {
        n=read(),m=read();
        for(int i=1;i<=m;i++)
        {
            int o=read();
            a[o].push_back(i);
        }
        for(int i=1;i<=n;i++)p[i]=read(),id[i]=i;
        k=read();
        for(int i=1;i<=k;i++)
        x[i]=read(),y[i]=read(),A[i]=read();
        x[++k]=1,y[k]=m,A[k]=INF; 
        solve(1,k,1,n);
        for(int i=1;i<=n;i++)
        if(ans[i]==k)printf("NIE
    ");
        else printf("%d
    ",ans[i]);
        return 0;
    }
  • 相关阅读:
    【WPF】ListBox GridViewColumn Header 文字换行、文字多行显示
    【Unity】讯飞语音识别SDK
    【Unity】UGUI无法修改UI元素的Pivot锚点位置
    【Unity】EasyTouch5触屏检测
    【Unity】序列化字典Dictionary的问题
    【WPF】自定义形状的按钮Button
    【WPF】图片按钮的单击与双击事件
    【Unity】ShareSDK、SMSSDK的基本使用与常见问题
    【Unity】不能新建项目
    【Java】移动JDK路径后,修改环境变量不生效 Error: could not open `C:Program FilesJavajre1.8.0_131libamd64jvm.cfg'
  • 原文地址:https://www.cnblogs.com/Zars19/p/6896895.html
Copyright © 2011-2022 走看看