当时做比赛的时候听说过这类用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. jQuery的toggle()的自动触发真烦人

    jQuery的toggle()方法应该是在鼠标点击后才会触发,现在的问题是在ready加载后就自动触发了,怎么回事呢? 答案是jQuery的版本问题,在1.9以后的版本toggle()就存在这个问题, ...

  2. 【转】 (C#)利用Aspose.Cells组件导入导出excel文件

    Aspose.Cells组件可以不依赖excel来导入导出excel文件: 导入: public static System.Data.DataTable ReadExcel(String strFi ...

  3. WPF 绑定三(绑定List中指定的字符串)

    xaml: <Window x:Class="WpfApplication1.Window3" xmlns="http://schemas.microsoft.co ...

  4. 老式浏览器兼容HTML5和CSS3的问题

      1.让老式浏览器支持HTML5   HTML5能为我们做的事儿很多,最为可口的就是语义化标签的应用,如果你已经在Chrome或者其他支持HTML5的浏览器上用过它的牛x,那这篇文章对你一定有用,因 ...

  5. WebApp

    目前的手机APP有三类:原生APP,WebAPP,HybridApp:HybridApp结合了前两类APP各自的优点,越来越流行. Hybrid App的兴起是现阶段移动互联网产业的一种偶然.移动互联 ...

  6. IE下无法保存Cookie和Session问题

    最近在做新的Web项目时,因为一个验证码无法保存在Cookie中,或者更确切地说是IE下无法保存Cookie的问题纠结了整整一天时间,考虑了多种原因,单步调试了不下三十次,也没有结果.甚至在无奈之下改 ...

  7. 原始套接字的简单tcp包嗅探

    原始套接字 sock_raw = socket(AF_INET , SOCK_RAW , IPPROTO_TCP); while(1) { data_size = recvfrom(sock_raw ...

  8. ASP.NET中利用Split实现对Checkbox的字符串分离放到DataTable里面

    一.背景 昨天唐欢问了我一个问题: 现在有一个CheckBox和一个Label如下图: 要实现选中CheckBox,点击下面打印按钮的时候要做成这个样子的如下图: 简单的说就是档案编号作为表中的一个列 ...

  9. 加载驱动模块时Device or resource busy的解决方法

    加载驱动模块时Device or resource busy的解决方法 加载驱动模块时Device or resource busy的解决方法 insmod或modprobe驱动模块时Device o ...

  10. 深度分析 Java 的 ClassLoader 机制(源码级别)

    写在前面:Java中的所有类,必须被装载到jvm中才能运行,这个装载工作是由jvm中的类装载器完成的,类装载器所做的工作实质是把类文件从硬盘读取到内存中,JVM在加载类的时候,都是通过ClassLoa ...