老司机破阵

Time Limit: 4500/1500MS (Java/Others)     Memory Limit: 65535/65535KB (Java/Others)

Submit  Status

老司机的女朋友被坏人抓起来了,护女票心切的老司机心急火燎的赶到坏人藏匿女票的地点想要救出她,但是老司机的神通广大坏人们早有耳闻,等老司机赶到时已经有一个法阵摆在他的面前阻挡着他。
法阵是一条直线上的n个法力元件构成的,老司机每次可以将一个法力元件击碎,法阵的能量就是所有 连贯的元件能量和的最大值 。
老司机非常的自信,他有一套自己的破除法阵的方案(虽然不见得是最佳)
老司机希望能实时的关注着法阵的能量,一旦能量允许,他就破阵而入,救出女票。
忙着破阵的老司机自然没有功夫去计算他每步操作之后法阵的能量,他只能将此重任交与在座的各位大侠,请大家助他一臂之力。

Input

第一行n (1 ≤ n ≤ 100,000),为法力元件数量
第二行有n个数,为每个法力元件所含有的能量ei(0 ≤ ei ≤ 1e9)
第三行有n个数,为老司机击破法力元件的顺序

Output

输出n行,为老司机每次击破法力元件后法阵的能量。

Sample input and output

Sample Input Sample Output
5
1 2 3 4 5
4 2 3 5 1
6
5
5
1
0
8
5 5 4 4 6 6 5 5
5 2 8 7 1 3 4 6
18
16
11
8
8
6
6
0

解题思路:

一上来就用线段树做了结果发现有更简单的做法。
线段树的话维护下区间最大连续和,单点更新,区间查询就行。
还有一种做法就是有stl,multiset大法,multiset就是不去重的set,这题用set的话,由于要放一个结构体,如何重载很麻烦,我搞不来,用multiset的话就不用考虑因为重复而不能插入的问题了。
用一个multiset维护存在的连续区间,每次把要删去的点所在的区间找出来,把它分裂成两个区间,再用一个multiset维护连续区间和,更新同理。
然而还有更简单的做法,就是把删点顺序倒过来当做添加点,从而把连续的点的值计算出来就好,这时候可以用并查集维护相邻的点并记录对应编号的值。
我好菜啊。%uestc大佬
线段树代码:
#include<bits/stdc++.h>
#define lson o<<1
#define rson o<<1|1
#define LL long long using namespace std;
const int maxn=1e5+5;
LL a[maxn];
struct p
{LL sum;LL rmax;LL lmax;LL max;void init(LL x){rmax=lmax=max=sum=x;}
}s[maxn<<2];
p operator +(const p&a, const p&b)
{p res;res.init(0);res.max=max(a.max, b.max);if(a.rmax>0 && b.lmax>0)res.max=max(res.max, a.rmax+b.lmax);res.lmax=a.lmax;if(a.max==a.sum)res.lmax=a.sum+b.lmax;res.rmax=b.rmax;if(b.sum==b.max)res.rmax=b.sum+a.rmax;res.sum=a.sum+b.sum;return res;
}
void build(int o, int l, int r)
{if(l==r){s[o].init(a[l]);return;}int mid=(l+r)>>1;build(lson, l, mid);build(rson, mid+1, r);s[o]=s[lson]+s[rson];return;
}p query(int o, int l, int r, int ll, int rr)
{if(ll<=l && r<=rr){return s[o];}int mid=(l+r)>>1;p res, L, R;res.init(0);if(ll<=mid){L=query(lson, l, mid, ll, rr);res=res+L;
//        printf("%d %d %lld %lld %lld\n", l, mid, L.max, L.lmax, L.rmax);}if(rr>mid){R=query(rson, mid+1, r, ll, rr);res=res+R;
//        printf("%d %d %lld %lld %lld\n", mid+1, r, R.max, R.lmax, R.rmax);}//    printf("%d %d %lld %lld %lld\n", l, r, res.max, res.lmax, res.rmax);return res;}
void change(int o, int l, int r, int x)
{if(l==x && l==r){s[o].rmax=s[o].lmax=s[o].max=0;return;}int mid=(l+r)>>1;if(x<=mid)change(lson, l, mid, x);else change(rson, mid+1, r, x);s[o]=s[lson]+s[rson];return;
}int main()
{int i, j, n;cin>>n;for(i=1; i<=n; i++)scanf("%d", &a[i]);build(1, 1, n);int x;LL ans;for(i=1; i<=n; i++){scanf("%d", &x);ans=0;if(1<=x-1)ans=query(1, 1, n, 1, x-1).max;if(x+1<=n)ans=max(ans, query(1, 1, n, x+1, n).max);printf("%lld\n", ans);change(1, 1, n, x);}}

multiset代码:

#include <bits/stdc++.h>
using namespace std;
const int maxn=1e5+5;
long long a[maxn];
struct nmb
{int l;int r;long long  value;bool operator < ( const nmb&b)const{return this->l<b.l;}
};
long long ans[maxn];
long long sum[maxn];multiset<nmb>s1;
multiset<long long >s2;
multiset<nmb>::iterator wh;
multiset<long long>::iterator y;int main()
{int x, n, i, j;cin>>n;nmb tmp;tmp.l=1, tmp.r=n, tmp.value=0;sum[0]=0;for(i=1; i<=n; i++){scanf("%lld", &a[i]);sum[i]=sum[i-1]+a[i];tmp.value+=a[i];}s1.insert(tmp);s2.insert(tmp.value);for(i=1; i<=n; i++){scanf("%d", &x);nmb tmp={x, x, 0};wh=s1.upper_bound(tmp);wh--;y=s2.find((*wh).value);s2.erase(y);nmb now;now.l=(*wh).l;now.r=x-1;now.value=sum[x-1]-sum[(*wh).l-1];//        printf("%d %d %lld\n", now.l, now.r, now.value);s1.insert(now);s2.insert(now.value);nmb now1;now1.l=x+1;now1.r=(*wh).r;now1.value=sum[now1.r]-sum[now1.l-1];
//        printf("%d %d %lld\n", now1.l, now1.r, now1.value);s1.insert(now1);s2.insert(now1.value);s1.erase(wh);wh=s1.begin();printf("%lld\n", *(s2.rbegin()));}}

uestc 1593 老司机破阵(线段树 or multiset)相关推荐

  1. UESTC 1593 老司机破阵 优先队列+双端链表

    老司机破阵 Time Limit: 4500/1500MS (Java/Others)     Memory Limit: 65535/65535KB (Java/Others) Submit  St ...

  2. codeforces 609F Frogs and mosquitoes 线段树+二分+multiset

    http://codeforces.com/problemset/problem/609/F There are n frogs sitting on the coordinate axis Ox. ...

  3. 解题报告:P3834 【模板】可持久化线段树 2(主席树)详解

    P3834 [模板]可持久化线段树 2(主席树) 题解 P3834 [[模板]可持久化线段树 2(主席树)] 1)静态求第k大数 可持久化线段树,不能用堆的方法存子结点了,所以用指针l表示左儿子r表示 ...

  4. 并查集:CDOJ1593-老司机破阵 (假的并查集拆除)

    老司机破阵 Time Limit: 4500/1500MS (Java/Others) Memory Limit: 65535/65535KB (Java/Others) Problem Descri ...

  5. 【 bzoj 4355 】 Play with sequence - 线段树乱搞

    先讲个故事... 据说某一天,claris扔了一道题到某群里面然后引起了不大的讨论~然后好学向上的whx同学发现了这题...聪明的whx想了很久...然后!whx发现看不懂claris给的暴力的证明. ...

  6. CDOJ-1057 秋实大哥与花(线段树区间更新)

    秋实大哥与花 Time Limit: 3000/1000MS (Java/Others)     Memory Limit: 65535/65535KB (Java/Others) Submit St ...

  7. 势能线段树/吉司机线段树-我没有脑子

    势能线段树/吉司机线段树 BZOJ3211 花神游历各国 BZOJ5312 冒险 BZOJ4355 Play with sequence BZOJ4695 最假女选手 \(A_i = max(A_i, ...

  8. 2020ICPC(南京) - Just Another Game of Stones(吉司机线段树+博弈)

    题目链接:点击查看 题目大意:给出一个长度为 nnn 的数列 aaa,现在需要执行 mmm 次操作,每次操作分为两种类型: 1lrx1 \ l \ r \ x1 l r x:对于所有 i∈[l,r]i ...

  9. HDU - 5306 Gorgeous Sequence(吉司机线段树)

    题目链接:点击查看 题目大意:给出 1 ~ n 的区间以及 m 次操作,每次操作分为三种形式: 0 l r val:对于区间 [ l , r ] ,a[ i ] = min ( a[ i ] , va ...

最新文章

  1. Codeforces Round #370 (Div. 2) A. Memory and Crow 水题
  2. 云时代的安全解读:云安全≠云计算安全
  3. JS中生成8位的随机数字
  4. Java Socket重要参数讲解
  5. c语言 if 按大小顺序排序,刚学c语言,老师让用if编一个五个数字从大到小的排序,有那个大神能帮我,谢谢啦...
  6. Visual Studio“Orcas”October 2006 CTP版下载
  7. 关于使用skimage.measure.shannon_entropy计算图像信息熵的问题
  8. 20200612每日一句
  9. 9106w android7,三星note4 SM-N9106W原厂刷机包4.4.4/5.0.1rom线刷包Root驱动
  10. python sqlite3加密_sqlite3加密
  11. ioncube php encode,ionCube PHP解密
  12. Excel如何合并两个单元格内容
  13. apache 服务器的 Option Indexes,AllowOverride,Order Allow,Deny 详解
  14. vue引入TweenMax.js
  15. java ftp 假死_FTPClient下载文件程序假死问题
  16. 推荐一个练习英语听力的网站
  17. 2021最火爆带字微信朋友圈背景
  18. f烽火ExMobi,移动应用平台的互联网思维
  19. Lucene2.9.1使用小结 (注释1)
  20. 《机电一体化系统设计》

热门文章

  1. c语言循环语循环控制,C语言.控制语循环语句.ppt
  2. 为什么HashMap使用红黑树而不使用AVL树
  3. 备忘录模式(设计模式_20)
  4. Windows 连接了网络浏览器不能上网
  5. st58服务器装系统,微pe硬盘安装系统教程
  6. 《信息系统安全》课后习题答案(陈萍)
  7. Excel-利用函数获取工作表标签名称(转)
  8. 小白也能看懂的零知识证明与zk-SNARKs
  9. 使用Mailgun WordPress插件增加订户
  10. 尚医通项目101-123:前台用户系统、登录注册、邮箱登录