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

    传送门

    分析

    一个整体二分的经典题

    每次二分得到两个答案区间,然后把现在的国家分别看属于哪个答案区间,递归求解即可

    代码

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<string>
    #include<algorithm>
    #include<cctype>
    #include<cmath>
    #include<cstdlib>
    #include<queue>
    #include<ctime>
    #include<vector>
    #include<set>
    #include<map>
    #include<stack>
    using namespace std;
    int n,m,k,now,t1[300100],t2[300100],d[300100];
    int sum[300100],id[300100],L[300100],R[300100],w[300100],Ans[300100];
    vector<int>wh[300100];
    inline int lb(int x){return x&(-x);}
    inline int q(int x){int res=0;while(x)res+=d[x],x-=lb(x);return res;}
    inline void add(int x,int s){while(x<=m)d[x]+=s,x+=lb(x);}
    inline bool ck(int x){
        int res=0;
        for(int i=0;i<wh[x].size();i++){
          res+=q(wh[x][i]);
          if(res>=sum[x])return 1;
        }
        return 0;
    }
    inline void update(int x,int s){
        add(L[x],s),add(R[x]+1,-s);
        if(R[x]<L[x])add(1,s);
    }
    inline void work(int x,int y,int le,int ri){
        if(x>y||le>ri)return;
        int mid=(le+ri)>>1,l1=0,l2=0;
        if(le==ri){
          for(int i=x;i<=y;i++)Ans[id[i]]=le;
          return;
        }
        while(now<mid)now++,update(now,w[now]);
        while(now>mid)update(now,-w[now]),now--;
        for(int i=x;i<=y;i++)
          if(ck(id[i]))t1[++l1]=id[i];
            else t2[++l2]=id[i];
        for(int i=1;i<=l1;i++)id[x+i-1]=t1[i];
        for(int i=1;i<=l2;i++)id[x+l1+i-1]=t2[i];
        if(l1)work(x,x+l1-1,le,mid);
        if(l2)work(x+l1,y,mid+1,ri);
    }
    int main(){
        int i,j,x;
        scanf("%d%d",&n,&m);
        for(i=1;i<=m;i++){
          scanf("%d",&x);
          wh[x].push_back(i);
        }
        for(i=1;i<=n;i++)scanf("%d",&sum[i]),id[i]=i;
        scanf("%d",&k);k++;
        for(i=1;i<k;i++)scanf("%d%d%d",&L[i],&R[i],&w[i]);
        L[k]=1,R[k]=m,w[k]=1e9+7;
        work(1,m,1,k);
        for(i=1;i<=n;i++)
          if(Ans[i]==k)puts("NIE");
            else printf("%d
    ",Ans[i]);
        return 0;
    }
  • 相关阅读:
    使用SDL2显示一张图片,SDL2上手贴
    两种方法操作其它mac应用的窗口
    golang子进程的启动和停止,mac与linux的区别
    自己动手,装一个液晶电视
    在Ubuntu上搭建kindle gtk开发环境
    macOS的OpenCL高性能计算
    量子计算及量子计算的模拟
    iPhone多次输入错误密码锁机后刷机恢复(原有内容会丢失)
    Day 2 总结
    Day 13 linux 的输入输出与管道的使用
  • 原文地址:https://www.cnblogs.com/yzxverygood/p/10354447.html
Copyright © 2011-2022 走看看