zoukankan      html  css  js  c++  java
  • BZOJ 2527 [Poi2011]Meteors:整体二分

    题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=2527

    题意:

      有n个国家和m个空间站,每个空间站都属于一个国家,一个国家可以有多个空间站,所有空间站按照顺序形成一个环,也就是说,m号空间站和1号空间站相邻。

      现在,将会有k场流星雨降临,每一场流星雨都会给区间[li,ri]内的每个空间站带来ai单位的陨石,每个国家都有一个收集陨石的目标pi,即第i个国家需要收集pi单位的陨石。

      询问:每个国家最早完成陨石收集目标是在第几场流星雨过后。

      1<=n,m,k<=300000

    题解:

      整体二分。

      将所有的国家一起二分。

      对于当前的答案区间[l,r],先模拟下前mid场的流星雨,用树状数组维护。

      再将已经超出目标pi的国家放到左边;把没达到目标的放在右边,并将这些国家的需求减去已经收集到的数量。

      然后恢复刚才的流星雨,带上相应的国家,分别左右递归。

      当访问到叶子节点的时候(即l==r),当前存的国家的答案即为l。

    AC Code:

      1 #include <iostream>
      2 #include <stdio.h>
      3 #include <string.h>
      4 #include <vector>
      5 #define MAX_N 300005
      6 #define INF 100000000
      7 
      8 using namespace std;
      9 
     10 int n,m,t;
     11 int ct[MAX_N];
     12 int nd[MAX_N];
     13 int L[MAX_N];
     14 int R[MAX_N];
     15 int a[MAX_N];
     16 int ans[MAX_N];
     17 long long sum[MAX_N];
     18 long long dat[MAX_N];
     19 vector<int> sp[MAX_N];
     20 
     21 void update(int k,int x)
     22 {
     23     while(k>0)
     24     {
     25         dat[k]+=x;
     26         k-=k&-k;
     27     }
     28 }
     29 
     30 long long query(int k)
     31 {
     32     long long sum=0;
     33     while(k<=m)
     34     {
     35         sum+=dat[k];
     36         k+=k&-k;
     37     }
     38     return sum;
     39 }
     40 
     41 void section(int l,int r,int x)
     42 {
     43     update(r,x);
     44     update(l-1,-x);
     45 }
     46 
     47 void meteor(int x,int f)
     48 {
     49     if(L[x]<=R[x]) section(L[x],R[x],a[x]*f);
     50     else section(L[x],m,a[x]*f),section(1,R[x],a[x]*f);
     51 }
     52 
     53 void read()
     54 {
     55     scanf("%d%d",&n,&m);
     56     for(int i=1;i<=m;i++)
     57     {
     58         scanf("%d",&ct[i]);
     59         sp[ct[i]].push_back(i);
     60     }
     61     for(int i=1;i<=n;i++)
     62     {
     63         scanf("%d",&nd[i]);
     64     }
     65     scanf("%d",&t);
     66     for(int i=1;i<=t;i++)
     67     {
     68         scanf("%d%d%d",&L[i],&R[i],&a[i]);
     69     }
     70     t++;
     71     L[t]=1; R[t]=t; a[t]=INF;
     72 }
     73 
     74 void dfs(vector<int> v,int l,int r)
     75 {
     76     if(l==r)
     77     {
     78         for(int i=0;i<v.size();i++)
     79         {
     80             ans[v[i]]=l;
     81         }
     82         return;
     83     }
     84     vector<int> vl,vr;
     85     int mid=(l+r)>>1;
     86     for(int i=l;i<=mid;i++)
     87     {
     88         meteor(i,1);
     89     }
     90     for(int i=0;i<v.size();i++)
     91     {
     92         sum[v[i]]=0;
     93     }
     94     for(int i=0;i<v.size();i++)
     95     {
     96         for(int j=0;j<sp[v[i]].size() && sum[v[i]]<nd[v[i]];j++)
     97         {
     98             int temp=sp[v[i]][j];
     99             sum[v[i]]+=query(temp);
    100         }
    101     }
    102     for(int i=0;i<v.size();i++)
    103     {
    104         if(sum[v[i]]>=nd[v[i]]) vl.push_back(v[i]);
    105         else nd[v[i]]-=sum[v[i]],vr.push_back(v[i]);
    106     }
    107     for(int i=l;i<=mid;i++)
    108     {
    109         meteor(i,-1);
    110     }
    111     dfs(vl,l,mid);
    112     dfs(vr,mid+1,r);
    113 }
    114 
    115 void solve()
    116 {
    117     memset(dat,0,sizeof(dat));
    118     vector<int> v;
    119     for(int i=1;i<=n;i++) v.push_back(i);
    120     dfs(v,1,t);
    121 }
    122 
    123 void print()
    124 {
    125     for(int i=1;i<=n;i++)
    126     {
    127         if(ans[i]==t) printf("NIE
    ");
    128         else printf("%d
    ",ans[i]);
    129     }
    130 }
    131 
    132 int main()
    133 {
    134     read();
    135     solve();
    136     print();
    137 }
  • 相关阅读:
    css之隐藏内容的方法
    字符串对象的各种方法
    javascript之自增自减典型运算(易错)
    Fuel 30 分钟快速安装OpenStack
    使用Sublime Text 3做Python开发
    Ubuntu 14.04.02 安装openvswitch-2.3.1
    linux 技巧:使用 screen 管理你的远程会话
    MQTT的学习研究(十七)Mosquitto简要教程(安装&使用)
    MQTT的学习研究(十六) MQTT的Mosquitto的window安装部署
    MQTT的学习研究(十五) MQTT 和android整合文章
  • 原文地址:https://www.cnblogs.com/Leohh/p/7994081.html
Copyright © 2011-2022 走看看