题目描述

有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. 2018.6.29 JavaScript

    一.使用JS数组实现冒泡排序 二.创建Teacher对象,添加(姓名.年龄.地址.学生对象[学生姓名,学生性别])属性 要求: 创建多个老师对象,每个老师下管理多个学生,显示每个老师下所有的学生信息 ...

  2. js 数组方法大集合,各方法是否改变原有的数组详解

    不会改变原来数组的有: concat()---连接两个或更多的数组,并返回结果. every()---检测数组元素的每个元素是否都符合条件. some()---检测数组元素中是否有元素符合指定条件. ...

  3. 前端安全之XSS和csrf攻击

    1.Csrf攻击概念: csrf攻击(Cross-site request forgery):跨站请求伪造; 2.Csrf攻击原理: 用户是网站A的注册用户,且登录进去,于是网站A就给用户下发cook ...

  4. Oracle表连接学习笔记

    目录 一.表连接类型 1.1 内连接 1.2 外连接 二.表连接方法 2.1 表连接方法分类 2.2 表连接方法特性区别 @ 一.表连接类型 表连接类型可以分为:内连接.外连接,在看<收获,不止 ...

  5. nginx反向代理与正向代理的区别

    http://blog.csdn.net/m13666368773/article/details/8060481

  6. Sass和gulp的简单了解

        一.sass  less    css预处理器        sass里面有2种语法  第一种语法是sass  后缀名必须是sass   第二种语法是scss  后缀名必须是scss      ...

  7. SummerVocation_Learning--java的线程死锁

    public class Test_DeadLock implements Runnable { ; static Object o1 = new Object(),o2 = new Object() ...

  8. Java 解决IE浏览器下载文件,文件名出现乱码问题

    /** * 区分ie 和其他浏览器的下载文件乱码问题 * @param request * @param fileName * @return */ public String getFileName ...

  9. WebService简单入门

    写在前面的话: 当两个人碰面后,产生了好感,如果需要得到双方的信息,那么双方的交流是必不可少的!应用程序也如此, 各个应用程序之间的交流就需要WebService来作为相互交流的桥梁! 项目目的: 程 ...

  10. Python入门必学:字符串和编码正确的使用方法

    字符编码,我们已经讲过了,字符串也是一种数据类型,但是,字符串比较特殊的是还有一个编码问题. 因为计算机只能处理数字,如果要处理文本,就必须先把文本转换为数字才能处理.最早的计算机在设计时采用8个比特 ...