51Nod 算法马拉松12 Rikka with sequences
当时做比赛的时候听说过这类用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的更多相关文章
- 51nod算法马拉松12
A 第K大区间 不妨考虑二分答案x,则问题转化成计算有多少个区间满足众数出现的次数>=x. 那么这个问题我们使用滑动窗口,枚举右端点,则左端点肯定单调递增,然后维护一个简单的数组就能资瓷添加元素 ...
- 51NOD 算法马拉松12
OTZ做出题目的神犇..断断续续改完了在这里存一下思路吧 A题:第K大区间题意:定义一个区间的值为其众数出现的次数.现给出n个数,求将所有区间的值排序后,第K大的值为多少. 分析:二分答案mid,任务 ...
- 51Nod 算法马拉松12 移数博弈
点进去发现并不是博弈QAQ 一开始考虑单调队列什么乱七八糟的发现根本做不出来 (没错我一直在想枚举最大值求次大值QAQ 不妨换个思路: 我们考虑枚举次大值求最大值 设当前为now, 设now之前第一个 ...
- 51NOD 算法马拉松8
题目戳这里:51NOD算法马拉松8 某天晚上kpm在玩OSU!之余让我看一下B题...然后我就被坑进了51Nod... A.还是01串 水题..怎么乱写应该都可以.记个前缀和然后枚举就行了.时间复杂度 ...
- 51nod 算法马拉松 34 Problem D 区间求和2 (FFT加速卷积)
题目链接 51nod 算法马拉松 34 Problem D 在这个题中$2$这个质数比较特殊,所以我们先特判$2$的情况,然后仅考虑大于等于$3$的奇数即可. 首先考虑任意一个点对$(i, j)$ ...
- 随便玩玩系列之一:SPOJ-RNG+51nod 算法马拉松17F+51nod 1034 骨牌覆盖v3
先说说前面的SPOJ-RNG吧,题意就是给n个数,x1,x2,...,xn 每次可以生成[-x1,x1]范围的浮点数,把n次这种操作生成的数之和加起来,为s,求s在[A,B]内的概率 连续形的概率 假 ...
- 51Nod 算法马拉松21(迎新年)
这次打算法马拉松是在星期五的晚上,发挥还算正常(废话,剩下的题都不会= =). 讲讲比赛经过吧. 8:00准时发题,拿到之后第一时间开始读. A配对,看上去像是二分图最大权匹配,一看范围吓傻了,先跳过 ...
- 51Nod 算法马拉松15 记一次悲壮而又开心的骗分比赛
OwO 故事的起源大概是zcg前天发现51Nod晚上有场马拉松,然后他就很开心的过去打了 神奇的故事就开始了: 晚上的时候我当时貌似正在写线段树?然后看见zcg一脸激动告诉我第一题有九个点直接输出B就 ...
- 51Nod 算法马拉松23 开黑记
惨啊……虽然开了半天黑,但是还是被dalao们踩了…… 第二次开黑,还是被卡在rank20了,我好菜啊……= = 写一写比赛经过吧…… 看到题之后习惯性都打开,A~D看上去似乎并没有什么思路,F应该是 ...
随机推荐
- 批处理cmd背景颜色
Pause Echo 其他提示语 & pause > nul pause暂停 COLOR 设置默认的控制台前景和背景颜色. COLOR [attr] attr 指定控制台输出的 ...
- 【Qt】Qt实战一二三【转】
简介 “我们来自Qt分享&&交流,我们来自Qt Quick分享&&交流”,不管你是笑了,还是笑了,反正我们是认真的.我们就是要找寻一种Hold不住的状态,来开始每一天的 ...
- JDK 动态代理实现原理
一.引言 Java动态代理机制的出现,使得Java开发人员不用手工编写代理类,只要简单地指定一组接口及委托类对象便能动态生成代理类.代理类会负责将所有方法的调用分派到委托对象上反射执行,在分派执行的过 ...
- Repeat Header / Keep Header Visible in Tables in RS 2008
You selected "Repeat header rows on each page" or "Keep header rows visible while scr ...
- python杂记-6(time&datetime模块)
#!/usr/bin/env python# -*- coding: utf-8 -*-import timeprint(time.clock())##返回处理器时间,3.3开始已废弃 , 改成了ti ...
- AJAX请求和跨域请求详解(原生JS、Jquery)
一.概述 AJAX 是一种在无需重新加载整个网页的情况下,能够更新部分网页的技术. AJAX = 异步 JavaScript 和 XML,是一种用于创建快速动态网页的技术.通过在后台与服务器进行少量数 ...
- 【转载】Powershell设置世纪互联Office365嵌套组发送权限
Start-Transcript ".\Set-GroupSendPermisionLog.txt" -Force function Get-DLMemberRecurse { $ ...
- 【nodejs】jade模板入门
使用jetbrians webstom创建空项目 1.创建package.json 引用依赖配置 { "name": "demojade", "des ...
- 团队博客作业Week1 Team Homework #3软件工程在北航
这次我们采访了一位大四的学姐,让她简单地谈了谈去年学习软件工程的经历和感受. 在完成软件工程大作业的过程中,由于计划安排与实际脱节,导致时间前松后紧,平均每周花在这门课上的时间大约有8个小时. 项目完 ...
- 保持程序在后台长时间运行-b
iOS为了让设备尽量省电,减少不必要的开销,保持系统流畅,因而对后台机制采用墓碑式的“假后台”.除了系统官方极少数程序可以真后台,一般开发者开发出来的应用程序后台受到以下限制:1.用户按Home之后, ...