Codeforces 1070C Cloud Computing 二分 + 树状数组 + 扫描线

                                                          Codeforces 1070C  Cloud Computing

将左右端点分配到1-n上的各个点,然后从1-n 进行扫描线处理,维护两个数状数组,c[i],b[i],  c[i]维护当前时间下,可用方案按时间排序的数量,b[i] 维护 i*c[i] 即价格和, 然后二分适合的价格,满足 数量 >= k, 如果 > k 回退一部分,注意longlong,wrong 样例 32,33 都是爆int的原因!

#include 

using namespace std;

const int maxn = 1e6+10;
typedef long long LL;

LL b[maxn];
LL c[maxn];
LL cc[maxn];
LL p[maxn];
LL n,k,m,li,ri,ci,pi;
vector  l[maxn];
vector  r[maxn];
int N = 1e6+2;
bool check(int mid)
{
    LL res = 0;
    for(int x = mid; x; x -= x&-x) res += c[x];
    if(res >= k) return true;
    else return false;
}

int main()
{

  scanf("%lld%lld%lld",&n,&k,&m);
  for(int i = 1; i <= m; i++)
  {
      scanf("%lld%lld%lld%lld",&li,&ri,&cc[i],&p[i]);
      l[li].push_back(i);
      r[ri].push_back(i);
  }
  memset(c,0,sizeof(c));
  memset(b,0,sizeof(b));
  LL ans = 0;
  for(int i = 1; i <= n; i++)
  {
    for(int j = 0; j < l[i].size(); j++)
       {
        int t = l[i][j];
      //  cout < 1)
    {
        int mid = st + (ed-st)/2;
        if(check(mid)) ed = mid;
        else st = mid;
    }

    LL num = 0,res = 0;
    for(int x = ed; x ; x-= x&-x)  num += c[x],res += b[x];

    LL num1 = 0;
    for(int x = st; x; x -= x&-x)  num1 += c[x];
    if(num1 == num)  ed = st;
    ans += res - max(0LL,(num-k))*ed;
    //cout <

 

你可能感兴趣的:(数据结构)