题目描述

有N个成员国。现在它发现了一颗新的星球,这颗星球的轨道被分为M份(第M份和第1份相邻),第i份上有第Ai个国家的太空站。

这个星球经常会下陨石雨。BIU已经预测了接下来K场陨石雨的情况。BIU的第i个成员国希望能够收集Pi单位的陨石样本。你的任务是判断对于每个国家,它需要在第几次陨石雨之后,才能收集足够的陨石。

输入

第一行是两个数N,M。

第二行有M个数,第i个数Oi表示第i段轨道上有第Oi个国家的太空站。

第三行有N个数,第i个数Pi表示第i个国家希望收集的陨石数量。

第四行有一个数K,表示BIU预测了接下来的K场陨石雨。

接下来K行,每行有三个数Li,Ri,Ai,表示第K场陨石雨的发生地点在从Li顺时针到Ri的区间中(如果Li<=Ri,就是Li,Li+1,...,Ri,否则就是Ri,Ri+1,...,m-1,m,1,...,Li),向区间中的每个太空站提供Ai单位的陨石样本。

输出

N行。第i行的数Wi表示第i个国家在第Wi波陨石雨之后能够收集到足够的陨石样本。如果到第K波结束后仍然收集不到,输出NIE。

样例输入

3 5
1 3 2 1 3
10 5 7
3
4 2 4
1 3 1
3 5 2

样例输出

3
NIE
1


题解

整体二分+树状数组

答案满足二分性质,所以考虑将询问离线下来,然后整体二分解决。

令$solve(b,e,l,r)$表示处理询问下标区间为[b,e],修改的区间为[l,r]的答案。

那么l=r时直接答案为l。

当l≠r时,先处理[l,mid]的修改,然后统计[b,e]内每个国家得到的数量,判断是否小于p。可以把所有空间站挂链,然后把每个点上的加起来。这个过程区间修改单点查询,可以使用树状数组。

有一个小trick:可以把修改区间设置为[1,k+1],这样当某个答案为k+1时,说明k个不能满足,输出-1.

然而最恶心的是:本题爆long long!

考虑:300000个空间站属于1个国家,300000次修改,每次修改加到[1,300000]上,加上10^9,这样乘起来会爆long long的2^63-1。

于是被迫改成中精度,把每次的数对10^15取模,最后判断时结合着高位和低位一起看即可。

#include <cstdio>
#include <cstring>
#include <algorithm>
#define N 300010
using namespace std;
typedef long long ll;
const ll mod = 1000000000000000ll;
ll w[N] , v[N] , f[N];
int m , a[N] , t[N] , lp[N] , rp[N] , head[N] , next[N] , ans[N];
void add(int x , ll a)
{
int i;
for(i = x ; i <= m ; i += i & -i) f[i] += a;
}
ll query(int x)
{
int i;
ll ans = 0;
for(i = x ; i ; i -= i & -i) ans += f[i];
return ans;
}
void solve(int b , int e , int l , int r)
{
int mid = (l + r) >> 1 , i , j , tl = b , tr = e;
ll c , vc;
if(l == r)
{
for(i = b ; i <= e ; i ++ ) ans[a[i]] = l;
return;
}
for(i = l ; i <= mid ; i ++ )
{
if(lp[i] <= rp[i]) add(lp[i] , v[i]) , add(rp[i] + 1 , -v[i]);
else add(lp[i] , v[i]) , add(m + 1 , -v[i]) , add(1 , v[i]) , add(rp[i] + 1 , -v[i]);
}
for(i = b ; i <= e ; i ++ )
{
if(!w[a[i]]) t[tl ++ ] = a[i];
else
{
for(c = vc = 0 , j = head[a[i]] ; j ; j = next[j])
{
c += query(j);
if(c >= mod) vc += c / mod , c %= mod;
else if(c < 0) vc += c / mod - 1 , c = (c % mod + mod) % mod;
}
if(vc || c >= w[a[i]]) t[tl ++ ] = a[i];
else w[a[i]] -= c , t[tr -- ] = a[i];
}
}
for(i = b ; i <= e ; i ++ ) a[i] = t[i];
for(i = l ; i <= mid ; i ++ )
{
if(lp[i] <= rp[i]) add(lp[i] , -v[i]) , add(rp[i] + 1 , v[i]);
else add(lp[i] , -v[i]) , add(m + 1 , v[i]) , add(1 , -v[i]) , add(rp[i] + 1 , v[i]);
}
solve(b , tr , l , mid) , solve(tl , e , mid + 1 , r);
}
int main()
{
int n , i , x , k;
scanf("%d%d" , &n , &m);
for(i = 1 ; i <= m ; i ++ ) scanf("%d" , &x) , next[i] = head[x] , head[x] = i;
for(i = 1 ; i <= n ; i ++ ) scanf("%lld" , &w[i]) , a[i] = i;
scanf("%d" , &k);
for(i = 1 ; i <= k ; i ++ ) scanf("%d%d%lld" , &lp[i] , &rp[i] , &v[i]);
solve(1 , n , 1 , k + 1);
for(i = 1 ; i <= n ; i ++ )
{
if(ans[i] >= 1 && ans[i] <= k) printf("%d\n" , ans[i]);
else puts("NIE");
}
return 0;
}

【bzoj2527】[Poi2011]Meteors 整体二分+树状数组的更多相关文章

  1. BZOJ2527 [Poi2011]Meteors 整体二分 树状数组

    原文链接http://www.cnblogs.com/zhouzhendong/p/8686460.html 题目传送门 - BZOJ2527 题意 有$n$个国家. 太空里有$m$个太空站排成一个圆 ...

  2. BZOJ2527[Poi2011]Meteors——整体二分+树状数组

    题目描述 Byteotian Interstellar Union (BIU) has recently discovered a new planet in a nearby galaxy. The ...

  3. 【BZOJ-2527】Meteors 整体二分 + 树状数组

    2527: [Poi2011]Meteors Time Limit: 60 Sec  Memory Limit: 128 MBSubmit: 831  Solved: 306[Submit][Stat ...

  4. BZOJ 2527 [Poi2011]Meteors (整体二分+树状数组)

    整体二分板题,没啥好讲的-注意是个环-还有所有贡献会爆longlong,那么只要在加之前判断一下有没有达到需要的值就行了- CODE #include <set> #include < ...

  5. bzoj 2527 Meteors - 整体二分 - 树状数组

    Description Byteotian Interstellar Union (BIU) has recently discovered a new planet in a nearby gala ...

  6. BZOJ 2527 [POI2011]MET-Meteors (整体二分+树状数组)

    题目大意:略 洛谷传送门 整体二分裸题 考虑只有一个国家的情况如何处理 对询问数量二分答案,暴力$O(m)$打差分,求前缀和验证,时间是$O(mlogK)$ 如果有$n$个国家,就是$O(nmlogK ...

  7. 【BZOJ3110】【整体二分+树状数组区间修改/线段树】K大数查询

    Description 有N个位置,M个操作.操作有两种,每次操作如果是1 a b c的形式表示在第a个位置到第b个位置,每个位置加入一个数c 如果是2 a b c形式,表示询问从第a个位置到第b个位 ...

  8. BZOJ_3110_[Zjoi2013]K大数查询_整体二分+树状数组

    BZOJ_3110_[Zjoi2013]K大数查询_整体二分+树状数组 Description 有N个位置,M个操作.操作有两种,每次操作如果是1 a b c的形式表示在第a个位置到第b个位置,每个位 ...

  9. 【bzoj3110】[Zjoi2013]K大数查询 整体二分+树状数组区间修改

    题目描述 有N个位置,M个操作.操作有两种,每次操作如果是1 a b c的形式表示在第a个位置到第b个位置,每个位置加入一个数c.如果是2 a b c形式,表示询问从第a个位置到第b个位置,第C大的数 ...

随机推荐

  1. codeforces 599D Spongebob and Squares

    很容易得到n × m的方块数是 然后就是个求和的问题了,枚举两者中小的那个n ≤ m. 然后就是转化成a*m + c = x了.a,m≥0,x ≥ c.最坏是n^3 ≤ x,至于中间会不会爆,测下1e ...

  2. UVA 11600 Masud Rana(概率dp)

    当两个城市之间有安全的道路的时候,他们是互相可到达的,这种关系满足自反.对称和传递性, 因此是一个等价关系,在图论中就对应一个连通块. 在一个连通块中,当前点是那个并不影响往其他连通块的点连边,因此只 ...

  3. python_28_dictionary补充

    #update:合并两个字典,如果有交叉就覆盖更新,没有交叉的就创建 info={ 'stu1101':'Liu Guannan', 'stu1102':'Wang Ruipu', 'stu1103' ...

  4. 漫谈 Clustering (1): k-means

    好久没有写 blog 了,一来是 blog 下线一段时间,而租 DreamHost 的事情又一直没弄好:二来是没有太多时间,天天都跑去实验室.现在主要折腾 Machine Learning 相关的东西 ...

  5. MacOS内核调试环境搭建

    http://ddeville.me/2015/08/using-the-vmware-fusion-gdb-stub-for-kernel-debugging-with-lldb http://dd ...

  6. 51nod——1402最大值、2479小b分糖果 (套路)

    1402最大值:正向从1到n,如果没有限制,就依次递增1,如果有限制,就取那个限制和递增到这的最小值.这样保证1和每个限制点后面都是符合题意的递增,但是限制点前面这个位置可能会有落差(之前递增多了). ...

  7. 【Django】Django开发中的日志输出

    开发环境:Ubuntu16.04+Django 1.11.9+Python2.7 一:使用自定义函数输出日志到log文件: import time def print_log(log): file_o ...

  8. Android系统编译环境及连接工具配置

    首先附上官网上关于环境搭建的地址:https://source.android.com/setup/build/initializing 官网目前建议的还是Ubuntu14.04,下面就是用的Ubun ...

  9. 短信验证码js

    var isSmsSend = false; function clickButtona(obj){ var obj = $(obj); var mobile=$("input[name=m ...

  10. JZOJ 5791. 【NOIP2008模拟】阶乘

    5791. [NOIP2008模拟]阶乘 (File IO): input:factorial.in output:factorial.out Time Limits: 1000 ms  Memory ...