当时做比赛的时候听说过这类用KD_Tree维护的数据结构题

然后知道是KD_Tree,然而并不知道怎么写QAQ

比赛完了之后%了一发代码

其基本思路是这样的:

1、首先我们把询问[L,R]看成二维平面上的点,那么对于任意修改[p,p]

当且仅当p>=L&&p<=R时会对答案有影响

对应到二维平面就是KD_Tree维护矩形区域和的经典操作啦

2、那么我们考虑对历史最小值的询问

先把修改转换为增量修改

我们可以在KD_Tree上维护两个标记

第一个是当前的ADD

第二个是历史所有的Minadd

这样在更改一下push_down函数就可以完成了

QAQ 高仿的代码,真是羞耻 QAQ

#include<cstdio>
#include<cstring>
#include<iostream>
#include<cstdlib>
#include<algorithm>
#include<queue>
using namespace std; typedef long long LL;
const int maxn=100010;
const int oo=0x7fffffff;
int n,m,D,cnt,rt;
int A[maxn],type[maxn],L[maxn],R[maxn];
LL Bit[maxn],ans[maxn]; void add(int x,int v){for(int i=x;i<=n;i+=(i&(-i)))Bit[i]+=v;}
LL ask(int x){
LL sum=0;
for(int i=x;i>=1;i-=(i&(-i)))sum+=Bit[i];
return sum;
}
int tot=0;
struct Node{
int d[2],mn[2],mx[2];
int L,R,id;
LL sum,add,ans,Minadd;
bool operator <(const Node &A){return d[D]<A.d[D];}
}t[maxn],tmp[maxn];
void up(int o){
for(int i=0;i<2;++i){
t[o].mn[i]=min(t[o].d[i],min(t[t[o].L].mn[i],t[t[o].R].mn[i]));
t[o].mx[i]=max(t[o].d[i],max(t[t[o].L].mx[i],t[t[o].R].mx[i]));
}return;
}
void push_1(int o,LL v){
if(!o)return;
t[o].ans=min(t[o].ans,t[o].sum+v);
t[o].Minadd=min(t[o].Minadd,t[o].add+v);
}
void push_2(int o,LL v){
if(!o)return;
t[o].sum+=v;t[o].add+=v;
t[o].ans=min(t[o].ans,t[o].sum);
t[o].Minadd=min(t[o].Minadd,t[o].add);
}
void push_down(int o){
if(t[o].Minadd){
push_1(t[o].L,t[o].Minadd);
push_1(t[o].R,t[o].Minadd);
t[o].Minadd=0;
}
if(t[o].add){
push_2(t[o].L,t[o].add);
push_2(t[o].R,t[o].add);
t[o].add=0;
}
}
void modify(int o,int p,int val){
if(!o)return;
push_down(o);
if(t[o].mx[0]<=p&&t[o].mn[1]>=p){push_2(o,1LL*val);return;}
if(t[o].d[0]<=p&&t[o].d[1]>=p)t[o].sum+=val,t[o].ans=min(t[o].ans,t[o].sum);
if(t[t[o].L].mn[0]<=p&&t[t[o].L].mx[1]>=p)modify(t[o].L,p,val);
if(t[t[o].R].mn[0]<=p&&t[t[o].R].mx[1]>=p)modify(t[o].R,p,val);
}
void insert(int &o,int x,int y,int id,int c){
if(!o){
o=++tot;t[o].d[0]=x;t[o].d[1]=y;
t[o].id=id;t[o].sum=t[o].ans=ask(y)-ask(x-1);
up(o);
return;
}
push_down(o);
if(c==0){
if(x<=t[o].d[0])insert(t[o].L,x,y,id,c^1);
else insert(t[o].R,x,y,id,c^1);
}else{
if(y<=t[o].d[1])insert(t[o].L,x,y,id,c^1);
else insert(t[o].R,x,y,id,c^1);
}up(o);
}
void DFS(int o){
if(!o)return;
push_down(o);
DFS(t[o].L);
tmp[++cnt]=t[o];
ans[t[o].id]=t[o].ans;
DFS(t[o].R);
}
void build(int &o,int L,int R,int c){
o=0;if(L>R)return;
int mid=(L+R)>>1;D=c;o=mid;
nth_element(tmp+L,tmp+mid,tmp+R+1);
t[o]=tmp[mid];
build(t[o].L,L,mid-1,c^1);
build(t[o].R,mid+1,R,c^1);
up(o);
}
int main(){
rt=0;
t[0].mn[0]=t[0].mn[1]=oo;
t[0].mx[0]=t[0].mx[1]=-oo;
scanf("%d%d",&n,&m);
for(int i=1;i<=n;++i)scanf("%d",&A[i]),add(i,A[i]);
for(int i=1;i<=m;++i){
scanf("%d%d%d",&type[i],&L[i],&R[i]);
if(type[i]==1){
add(L[i],R[i]-A[L[i]]);
R[i]=R[i]-A[L[i]];
A[L[i]]+=R[i];
}
}
int blo=2000;
for(int i=m;i>=1;--i){
if(type[i]==1)modify(rt,L[i],-R[i]),add(L[i],-R[i]);
else insert(rt,L[i],R[i],i,0);
if(i%blo==0){
cnt=0;DFS(rt);rt=0;
build(rt,1,cnt,0);
}
}
cnt=0;DFS(rt);
for(int i=1;i<=m;++i){
if(type[i]==2)printf("%lld\n",ans[i]);
}return 0; }

  

51Nod 算法马拉松12 Rikka with sequences的更多相关文章

  1. 51nod算法马拉松12

    A 第K大区间 不妨考虑二分答案x,则问题转化成计算有多少个区间满足众数出现的次数>=x. 那么这个问题我们使用滑动窗口,枚举右端点,则左端点肯定单调递增,然后维护一个简单的数组就能资瓷添加元素 ...

  2. 51NOD 算法马拉松12

    OTZ做出题目的神犇..断断续续改完了在这里存一下思路吧 A题:第K大区间题意:定义一个区间的值为其众数出现的次数.现给出n个数,求将所有区间的值排序后,第K大的值为多少. 分析:二分答案mid,任务 ...

  3. 51Nod 算法马拉松12 移数博弈

    点进去发现并不是博弈QAQ 一开始考虑单调队列什么乱七八糟的发现根本做不出来 (没错我一直在想枚举最大值求次大值QAQ 不妨换个思路: 我们考虑枚举次大值求最大值 设当前为now, 设now之前第一个 ...

  4. 51NOD 算法马拉松8

    题目戳这里:51NOD算法马拉松8 某天晚上kpm在玩OSU!之余让我看一下B题...然后我就被坑进了51Nod... A.还是01串 水题..怎么乱写应该都可以.记个前缀和然后枚举就行了.时间复杂度 ...

  5. 51nod 算法马拉松 34 Problem D 区间求和2 (FFT加速卷积)

    题目链接  51nod 算法马拉松 34  Problem D 在这个题中$2$这个质数比较特殊,所以我们先特判$2$的情况,然后仅考虑大于等于$3$的奇数即可. 首先考虑任意一个点对$(i, j)$ ...

  6. 随便玩玩系列之一:SPOJ-RNG+51nod 算法马拉松17F+51nod 1034 骨牌覆盖v3

    先说说前面的SPOJ-RNG吧,题意就是给n个数,x1,x2,...,xn 每次可以生成[-x1,x1]范围的浮点数,把n次这种操作生成的数之和加起来,为s,求s在[A,B]内的概率 连续形的概率 假 ...

  7. 51Nod 算法马拉松21(迎新年)

    这次打算法马拉松是在星期五的晚上,发挥还算正常(废话,剩下的题都不会= =). 讲讲比赛经过吧. 8:00准时发题,拿到之后第一时间开始读. A配对,看上去像是二分图最大权匹配,一看范围吓傻了,先跳过 ...

  8. 51Nod 算法马拉松15 记一次悲壮而又开心的骗分比赛

    OwO 故事的起源大概是zcg前天发现51Nod晚上有场马拉松,然后他就很开心的过去打了 神奇的故事就开始了: 晚上的时候我当时貌似正在写线段树?然后看见zcg一脸激动告诉我第一题有九个点直接输出B就 ...

  9. 51Nod 算法马拉松23 开黑记

    惨啊……虽然开了半天黑,但是还是被dalao们踩了…… 第二次开黑,还是被卡在rank20了,我好菜啊……= = 写一写比赛经过吧…… 看到题之后习惯性都打开,A~D看上去似乎并没有什么思路,F应该是 ...

随机推荐

  1. (转)HTML5游戏如何挣钱?2条经验让你每款赚3万刀

    原文作者:Alexander Krug,是世界上最大的HTML5游戏平台的运营商SOFTGAMES的CEO. 现今苹果App Store当中的应用数量可以以海量来形容,最新发布的应用对排行榜的冲击力也 ...

  2. VMware Workstation中linux(centos)与windows7共享文件夹

    引用网站有: http://www.jb51.net/LINUXjishu/161994.html http://www.cnblogs.com/xiehy/archive/2011/12/19/22 ...

  3. 压缩html 减小存储空间

    压缩html 减小存储空间 方法一.php代码,清除换行符,清除制表符,去掉注释标记 /** * 压缩html : 清除换行符,清除制表符,去掉注释标记 * @param $string * @ret ...

  4. Reveal 配置与使用

    http://www.th7.cn/Program/IOS/201608/939231.shtml http://www.jianshu.com/p/abac941c2e8e 这个比较好.http:/ ...

  5. js中的数组Array定义与sort方法使用示例

    Array的定义及sort方法使用示例 Array数组相当于java中的ArrayList  定义方法:  1:使用new Array(5  )创建数组 var ary = new Array(5): ...

  6. mikrotik/IPSec Dynamic End points Updater.rsc

    # IPSec Peer/Policy Updater for Dynamic WAN addresses # ============================================ ...

  7. SQL中的自定义函数Function

    先给出一个链接吧,别人写的:http://www.cnblogs.com/diony/archive/2010/12/17/1909014.html 总结得很全面,感谢感谢!自己练习了一下后面的例子, ...

  8. java的JVM机制

    1.jre:java运行环境 提供一个JVM和一些基础类库.2.只安装jre以后,机器就具备了运行java程序的条件.但是不具备开发java程序的条件.安装JDK以后,在c:/program file ...

  9. MySQL创建复合索引

    在MySQL数据库中,创建复合索引的时候,不知道在创建过程中哪个列在前面,哪个列该在后面,用以下方式即可: select count(distinct first_name)/count(*) as ...

  10. JAVA算术运算符、关系运算符和位运算符

    算术运算符 1.java的算数运算符包括+(加).-(减).*(乘)./(除).%(取余),在运算过程中出现的隐式转换原则和C语言一样:2. 高位数据向低位数据转化要使用强制转化: 关系运算符 1.j ...