此题神矣。。。一开始我先想的第二问。。。想到一个线段树做法。。。对于最优子序列的下标序列,i[2k]~i[2k+1]这段区间选一个最小值位置为pos再在pos~i[2k+1]选一个最大值,更新答案。。。再同样处理剩下的区间i[2k]~pos-1。。。数据随机的话O(lognlogn)但是。。。第一问的更新就成了瓶颈。。。

后来看了题解才知道。。。不能把i[2k]~i[2k+1]分为一组。。。要把i[2k-1]~i[2k]分为一组。。。第一问更新用差值。。。即设d[i]=u[i]-u[i-1],这样更新就只需更新最多2个点。。。

题解上细节错误太多了。。。但是想法是很明了的。。。由于把i[2k-1]~i[2k]分为一组。。。对于调整i[2k]~i[2k+1],即将d数组上对应负区间上操作,我们在d数组上建立线段树,查询sum和max就可以了。。。至于区间可操作性。。。只要不包含d[2]或d[n]即可。。。

这样一颗zkw线段树维护d数组。。。一颗splay维护所有负区间左右端点(包括不可操作区间)。。。一颗splay维护可操作负区间可贡献的权值。。。为了不使自己写迷糊了。。。将以上写成class或struct就可以了。。。11kb很好(不要被吓到了。。。只不过缩进很长而已。。。还有一些注释)。。。根本用不到那么多数据结构。。。有一点注意要时刻判断你在splay中查找到的值。。。以及zkw的修改和splay的修改的先后。。。

Code:总时间十个Case7.5S,标程9S+。。。双旋splay果然强大。。。

#include<cstdio>
#include<cstdlib>
#include<cmath>
#include<cstring>
typedef long long ll;
const ll oo=1000000000;
class splayinter
{
private:int rfs,rffs,rch,fs,ffs,root,size;bool p,q;int f[200005],son[200005][2],keyl[200005],keyr[200005];inline void rotate(int s,bool t){rfs=f[s],rffs=f[rfs],rch=son[s][t^1];if (rffs)if (son[rffs][0]==rfs) son[rffs][0]=s; else son[rffs][1]=s;f[s]=rffs;son[s][t^1]=rfs;f[rfs]=s;son[rfs][t]=rch;if (rch) f[rch]=rfs;}inline void splay(int s){if (!s) return;fs=f[s],ffs=f[fs];while (fs && (son[fs][0]==s || son[fs][1]==s)){if (ffs && (son[ffs][0]==fs || son[ffs][1]==fs)){p=(son[ffs][1]==fs);q=(son[fs][1]==s);if (p==q)rotate(fs,p),rotate(s,q);elserotate(s,q),rotate(s,p);}elseif (son[fs][0]==s) rotate(s,0); else rotate(s,1);fs=f[s],ffs=f[fs];}root=s;}
public:inline void effectkey(int pos,int &l,int &r){l=keyl[pos];r=keyr[pos];}inline int find(int key){int now=root,last=0;while (now){last=now;if ((keyl[now]<=key)&&(key<=keyr[now])) return now;if (key<keyl[now]) now=son[now][0]; else now=son[now][1];}while (key<keyl[last]) last=f[last];return last;}inline int find(int kl,int kr){int now=root,last=0;while (now){last=now;if ((keyl[now]<=kl)&&(kr<=keyr[now])) return now;if (kr<keyl[now]) now=son[now][0]; else now=son[now][1];}while (kr<keyl[last]) last=f[last];return last;}inline int findleft(int pos){while (son[pos][0])pos=son[pos][0];return pos;}inline void insert(int kl,int kr){if (kr<kl) return;int pos=find(kl,kr);if (!pos) return;splay(pos);int ch=son[pos][1];son[pos][1]=++size;f[size]=pos;keyl[size]=kl;keyr[size]=kr;son[size][1]=ch;if (ch) f[ch]=size;}inline void eraser(int pos){if (!pos) return;splay(pos);int tmpch=son[pos][1];if (!tmpch){root=son[pos][0];f[root]=0;son[pos][0]=keyl[pos]=keyr[pos]=0;}else{f[tmpch]=0;root=tmpch;son[pos][1]=0;int left=findleft(tmpch);splay(left);son[left][0]=son[pos][0];if (f[son[pos][0]]) f[son[pos][0]]=left;son[pos][0]=keyl[pos]=keyr[pos]=0;}}inline void eraser(int kl,int kr){if (kr<kl) return;int pos=find(kl,kr);if (keyl[pos]!=kl || keyr[pos]!=kr) return;eraser(pos);}inline void creat(){root=1;size=1;memset(keyl,0,sizeof(keyl));memset(keyr,0,sizeof(keyr));memset(f,0,sizeof(f));memset(son,0,sizeof(son));keyl[1]=keyr[1]=1;rfs=rffs=rch=fs=ffs=0;p=q=0;}
} splayi;
class splayval
{
private:int rfs,rffs,rch,fs,ffs,root,size;bool p,q;int f[200005],son[200005][2],sums[200005];ll val[200005],totv[200005];inline void update(int s){sums[s]=sums[son[s][0]]+sums[son[s][1]]+1;totv[s]=totv[son[s][0]]+totv[son[s][1]]+val[s];}inline void rotate(int s,bool t){rfs=f[s],rffs=f[rfs],rch=son[s][t^1];if (rffs)if (son[rffs][0]==rfs) son[rffs][0]=s; else son[rffs][1]=s;f[s]=rffs;son[s][t^1]=rfs;f[rfs]=s;son[rfs][t]=rch;if (rch) f[rch]=rfs;update(rfs);}inline void splay(int s){if (!s) return;fs=f[s],ffs=f[fs];while (fs && (son[fs][0]==s || son[fs][1]==s)){if (ffs && (son[ffs][0]==fs || son[ffs][1]==fs)){p=(son[ffs][1]==fs);q=(son[fs][1]==s);if (p==q)rotate(fs,p),rotate(s,q);elserotate(s,q),rotate(s,p);}elseif (son[fs][0]==s) rotate(s,0); else rotate(s,1);fs=f[s],ffs=f[fs];}root=s;update(s);}
public:inline int find(ll key){int now=root,last=0;while (now){last=now;if (val[now]==key) return now;if (key<val[now]) now=son[now][0]; else now=son[now][1];}while (key<val[last]) last=f[last];return last;}inline int findleft(int pos){while (son[pos][0])pos=son[pos][0];return pos;}inline int mintime(ll key){if (totv[root]<key) return -1;int now=root,ans=0;while (now && (key>0)){if (totv[son[now][1]]>=key)now=son[now][1];elseif (totv[son[now][1]]+val[now]>=key) return ans+sums[son[now][1]]+1;else{ans+=(sums[son[now][1]]+1);key-=(totv[son[now][1]]+val[now]);now=son[now][0];}}return ans;}inline void insert(ll va){if (va<0) return;int pos=find(va);if (!pos) return;splay(pos);int ch=son[pos][1];son[pos][1]=++size;val[size]=va;f[size]=pos;son[size][1]=ch;if (ch) f[ch]=size;update(size);update(pos);}inline void eraserpos(int pos){if (!pos) return;splay(pos);int tmpch=son[pos][1];if (!tmpch){root=son[pos][0];f[root]=0;son[pos][0]=son[pos][1]=val[pos]=totv[pos]=sums[pos]=0;}else{f[tmpch]=0;son[pos][1]=0;root=tmpch;int left=findleft(tmpch);splay(left);son[left][0]=son[pos][0];if (son[pos][0]) f[son[pos][0]]=left;son[pos][0]=val[pos]=totv[pos]=sums[pos]=0;update(left);}}inline void eraserkey(ll va){int pos=find(va);if ((!pos)||(va!=val[pos])) return;eraserpos(pos);}inline void creat(){root=1;size=1;memset(val,0,sizeof(val));memset(f,0,sizeof(f));memset(son,0,sizeof(son));memset(sums,0,sizeof(sums));memset(totv,0,sizeof(totv));rfs=rffs=rch=fs=ffs=0;p=q=0;}
} splayv;
class zkwinter
{
private:ll maxt[262149],sumt[262149];int mm;inline ll max(ll a,ll b){if (a>b) return a;return b;}
public:inline ll askval(int l,int r){l=l+mm-1;r=r+mm+1;ll ans1=0;ll ans2=-oo;while (l^r^1){if (!(l&1)) {ans1+=sumt[l^1];if (maxt[l^1]>ans2) ans2=maxt[l^1];}if (r&1) {ans1+=sumt[r^1];if (maxt[r^1]>ans2) ans2=maxt[r^1];}l>>=1;r>>=1;}return ans1-ans2;}inline void modify(int pos,ll val){pos+=mm;maxt[pos]+=val;sumt[pos]+=val;pos>>=1;while (pos){maxt[pos]=max(maxt[pos<<1],maxt[(pos<<1)+1]);sumt[pos]+=val;pos>>=1;}}inline void creat(ll *a,int n){memset(maxt,0,sizeof(maxt));memset(sumt,0,sizeof(sumt));mm=1<<(int)(log2(n)+1);while (mm<n) mm<<1;maxt[mm]=-oo;for (int i=1;i<=n;i++) maxt[i+mm]=sumt[i+mm]=a[i];maxt[mm+1]=-oo;for (int i=n+1+mm;i<=(mm<<1);i++) maxt[i]=-oo;for (int i=mm-1;i>=1;i--) maxt[i]=max(maxt[i<<1],maxt[(i<<1)+1]),sumt[i]=sumt[i<<1]+sumt[(i<<1)+1];}
} zkw;
ll a[100005],b[100005],positive=0;
int task=0,q=0,n=0;
inline void init()
{scanf("%d%d",&n,&q);int i=0;for (i=1;i<=n;i++)scanf("%I64d",&a[i]);int l=0,r=-1;for (i=2;i<=n;i++) b[i]=a[i]-a[i-1];zkw.creat(b,n);for (i=2;i<=n;i++)if (b[i]>0){positive+=b[i];if (r-l>=0){splayi.insert(l,r);if ((l!=2)&&(r!=n)) splayv.insert(-zkw.askval(l,r));l=0,r=-1;}}else{if ((b[i-1]>0) || (i==2)) l=i,r=i-1;r++;}if (b[n]<0)if (r-l>=0)splayi.insert(l,r);
}
inline void add(int pos,ll val)
{ll last=b[pos];b[pos]+=val;ll now=b[pos];if (last>0)if (now>0){positive+=val;zkw.modify(pos,val);//Case 1}else{positive-=last;int nl=pos,nr=pos;if (b[pos-1]<0){int inter=splayi.find(pos-1),interl=0,interr=0;splayi.effectkey(inter,interl,interr);splayi.eraser(inter);if (interl!=2) splayv.eraserkey(-zkw.askval(interl,interr));nl=interl;}if (b[pos+1]<0){int inter=splayi.find(pos+1),interl=0,interr=0;splayi.effectkey(inter,interl,interr);splayi.eraser(inter);if (interr!=n) splayv.eraserkey(-zkw.askval(interl,interr));nr=interr;}zkw.modify(pos,val);splayi.insert(nl,nr);if ((nl!=2)&&(nr!=n)) splayv.insert(-zkw.askval(nl,nr));//Case 4}elseif (now>0){positive+=now;int inter=splayi.find(pos),interl=0,interr=0;splayi.effectkey(inter,interl,interr);splayi.eraser(inter);if ((interl!=2)&&(interr!=n))splayv.eraserkey(-zkw.askval(interl,interr));zkw.modify(pos,val);int l1=interl,r1=pos-1,l2=pos+1,r2=interr;if (l1<=r1){splayi.insert(l1,r1);if (l1!=2) splayv.insert(-zkw.askval(l1,r1));}if (l2<=r2){splayi.insert(l2,r2);if (r2!=n) splayv.insert(-zkw.askval(l2,r2));}//Case 3}else{int inter=splayi.find(pos),interl=0,interr=0;splayi.effectkey(inter,interl,interr);if ((interl<=2)||(interr==n)){zkw.modify(pos,val);return;}int nowsum=-zkw.askval(interl,interr);splayv.eraserkey(nowsum);zkw.modify(pos,val);splayv.insert(-zkw.askval(interl,interr));//Case 2}
}
inline void prepare()
{memset(a,0,sizeof(a));memset(b,0,sizeof(b));splayi.creat();splayv.creat();positive=0;n=q=0;
}
int main()
{freopen("joy.in","r",stdin);freopen("joy.out","w",stdout);int operch=0,l=0,r=0;ll c=0;for (scanf("%d",&task);task;task--){prepare();init();for (;q;q--){scanf("%d",&operch);if (operch==0){scanf("%d%d%I64d",&l,&r,&c);if (l!=1) add(l,c);if (r!=n) add(r+1,-c);}elseprintf("%I64d %d\n",positive,splayv.mintime(positive));}}return 0;
}

WC 2011 joy相关推荐

  1. [WC 2011]Xor

    Description Input 第一行包含两个整数N和 M, 表示该无向图中点的数目与边的数目. 接下来M 行描述 M 条边,每行三个整数Si,Ti ,Di,表示 Si 与Ti之间存在 一条权值为 ...

  2. linux sort,uniq,cut,wc命令详解

    linux sort,uniq,cut,wc命令详解 sort sort 命令对 File 参数指定的文件中的行排序,并将结果写到标准输出.如果 File 参数指定多个文件,那么 sort 命令将这些 ...

  3. 这是目录以下是本人认为wc的C++

    同理qt也一样!作者: 时间: 出处: 缩略图: 标题:index for wc solution内容: 这是目录以下是本人认为wc的C++可做题(即有意义的)ok表示2002:fence(ok) h ...

  4. 2011大学英语四级核心高频词汇表免费下载

    2011年大学英语四级核心高频词汇表 abandon vt.丢弃:放弃,抛弃 ability n.能力:能耐,本领 abnormal a.不正常的:变态的 aboard ad.在船(车)上:上船 ab ...

  5. 2011年11月CET4

    2011年12月大学英语四级真题 Part Ⅰ                                             Writing                          ...

  6. Business Insider点评2011年最佳创业公司20强

    北京时间12月6日消息,据国外媒体报道,国外科技圈内点评了2011年最佳创业公司20强.以下是Business Insider对这20家最佳创业公司的点评. Simple 一款帮助去除银行年费的全新的 ...

  7. 2011最新《美味/一吻巴黎》1024x560.BD中字迅雷下载

    ◎译 名 美味/一吻巴黎(港)/爱情好意外(台) ◎片 名 La delicatesse/Delicacy ◎年 代 2011 ◎国 家 法国 ◎类 别 爱情/喜剧 ◎语 言 法语 ◎字 幕 中字 ◎ ...

  8. linux02-自动部署、awk/sed/cron/cut/wc/uniq

    自动部署 boot.sh #!/bin/bash SERVERS="192.168.250.131 192.168.250.132" PASSWORD=root BASE_SERV ...

  9. 2011年新年英语祝福短信

    最好的足球网址导航:265足球之家 最好的足球网址导航:265足球之家 2011年新年英语祝福短信: Good luck in the year ahead! 祝吉星高照! May you come ...

最新文章

  1. trigger() --工作中问题nav样式
  2. php mysqli还原数据库,PHP mysqli操作数据库
  3. XCTF-高手进阶区:PHP2
  4. linux下用户命令
  5. Github版本控制——基础操作
  6. 基于Python实现自动慢查询分析,邮件自动发送
  7. 代码静态检查工具PC-Lint运用实践
  8. pythonsys用法_Python 使用sys模块
  9. stm32CubeMx lwip + freeRTOS
  10. SAP表维护自动带出对象属性
  11. 2020年最新版CSDN博客排名第一名的博客
  12. mysql的分页——limit、offset
  13. 内网渗透靶场 Vulnstack(二)
  14. c语言写字机器人,写字机器人(基于STM32简易实现)
  15. 键盘连不上计算机,电脑键盘连接不上电脑是怎么回事
  16. JAVA word转pdf高清无乱码版本(图片也可以的)
  17. 社区计算机知识,社区公共基础知识备考指导——计算机知识
  18. 【CH376】关于CH376的一些使用总结
  19. uni-app 父组件无法获取到子组件传来的值,为undefined;父子组件传值undefined
  20. 冒险解谜游戏:恩科迪亚Encodya mac中文版

热门文章

  1. BCC异或校验及BCC在Matlab中的实现
  2. 笔记2——一元二次方程平方根(包含实部与虚部)
  3. 调用阿里云身份证识别OCR
  4. VBA中的10种循环语句
  5. KVC与KVO的不同
  6. 敏捷教练的六顶帽子|洞见
  7. 探讨下一步的网游(二)未来不是“游戏+SNS”而是“游戏SNS”
  8. 使用 WebRTC 广播 IP 摄像头视频流
  9. uni-app计算入学(职)时间要比离职时间晚
  10. 金工如何运用计算机思维,金工实训心得体会