caioj1097: [视频]树状数组1(快速求和计算) cdq分治入门
这题虽然是个树状数组,但是也可以用cdq分治做啊~~,这个就是一个浅显的二维偏序的应用?
cdq分治和普通的分治有什么区别?
举个栗子:有4个小朋友,你请他们吃饭,假如你分治搞,就会分成很多子问题——1~1号小朋友有多少个来,2~2号小朋友有多少个来,然后程序就会回溯,你就知道1~2号小朋友有多少个来,最后你就知道1~4号小朋友有多少个来了。
而cdq分治呢?同样是4个小朋友,但是要照顾小朋友的心情,第i号小朋友的开心程度是1~i-1号小朋友有多少个来,你想知道小朋友们的心情,有可能心情不好就不来了,那先往左右搜,然后要把心情的影响加上。可能这个栗子不是很贴切,但是我想说的就是cdq分治中,前面的结果会影响后面的,而且,这个算法做题只能离线。
那么,我是拿了这题水题来理解。
俩操作,一个单点修改,一个询问区间和。
那么我们还是照样按前缀和的做法,把询问分成求1~l-1和1~r。
那么离线做,按照输入的顺序放进结构体,这个时候你一定发现了,对于一个询问,对它有影响的修改,就是在它前面操作的,并且修改位置也在它询问位置前面的。那么,实际上这个结构体已经是按照操作的顺序排好了,那么要解决的就是位置的问题。具体的做法,就是按照它的位置,做一次归并排序。
具体怎么做呢,首先先把区间分成l~mid和mid+1~r,当前我们要维护的,就是mid+1~r的全部询问,要先让两边都递归下去,令l~mid的询问解决,以及mid+1~r里的修改施加影响。
那么在归并的过程中,记录一个sum,表示左边已经l~当前归并到的位置的修改值的和,然后当遇到右边的询问,就将影响释放下去,一直这样做下去,当按x排好序了,对于mid+1~r中的询问,l~r的全部影响都已经解决,最后回溯接受更前面的影响,或者去影响后面的其他询问(你这样归排岂不是把一开始操作的顺序打乱了!?不用担心,l~mid的输入顺序每一个都是比mid+1~r大的,l~mid的顺序改变并不会影响后面的修改)
#include<cstdio>
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<cmath>
using namespace std;
typedef long long LL; int n,m;
struct node
{
int x,tp;LL v;
//tp=1表示这个是修改操作,x表示修改哪个位置,v表示要加上的值
//tp=2,3表示这个是问1~x的前缀和,v表示这个影响第几个答案
}a[],t[];int len=;
void ins(int x,int tp,int v)
{
len++;
a[len].x=x;a[len].tp=tp;a[len].v=v;
}
LL ans[];int ansl=;//答案数组
bool check(node n1,node n2)
{
if(n1.x<n2.x||(n1.x==n2.x&&n1.tp<n2.tp))return true;
return false;
}
void cdq(int l,int r)
{
if(l==r)return ;
int mid=(l+r)/;
cdq(l,mid);cdq(mid+,r); LL sum=;//sum表示l~t[p].x的修改的和
int i=l,j=mid+,p=l;
while(i<=mid&&j<=r)
{
if(check(a[i],a[j])==true)//只统计左边区间内的修改值,因为右边的修改值已经在递归里影响过了
{
if(a[i].tp==)sum+=a[i].v;
t[p++]=a[i++];
}
else//将左边的影响影响右边
{
if(a[j].tp==)ans[a[j].v]-=sum;
else if(a[j].tp==)ans[a[j].v]+=sum;
t[p++]=a[j++];
}
}
while(i<=mid)t[p++]=a[i++];
while(j<=r)
{
if(a[j].tp==)ans[a[j].v]-=sum;
else if(a[j].tp==)ans[a[j].v]+=sum;
t[p++]=a[j++];
} for(int i=l;i<=r;i++)a[i]=t[i];
} char ss[];
int main()
{
int x,l,r;LL v;
scanf("%d%d",&n,&m);
for(int i=;i<=m;i++)
{
scanf("%s",ss+);
if(ss[]=='C')
{
scanf("%d%lld",&x,&v);
ins(x,,v);
}
else//利用前缀和的思想,把查询操作分为两部分
{
scanf("%d%d",&l,&r);
ansl++;ins(l-,,ansl);ins(r,,ansl);
}
}
cdq(,len);
for(int i=;i<=ansl;i++)printf("%lld\n",ans[i]);
return ;
}
caioj1097: [视频]树状数组1(快速求和计算) cdq分治入门的更多相关文章
- poj 1195:Mobile phones(二维树状数组,矩阵求和)
Mobile phones Time Limit: 5000MS Memory Limit: 65536K Total Submissions: 14489 Accepted: 6735 De ...
- HRBUST 1161 树状数组区间更新求和
Leyni Time Limit: 3000 MS Memory Limit: 65536 K Total Submit: 267(64 users) Total Accepted: 82(57 us ...
- P3374 【模板】树状数组 1
树状数组模板题,用cdq分治做 cdq分治: 分:把l到r分成两个区间操作 治:对每个分出来的区间进行操作 但是cdq分治和一般分治不同的是,一般的分治左右两个区间互不干扰,但是cdq分治处理的是区间 ...
- 【bzoj3262】陌上花开 CDQ分治+树状数组
题目描述 有n朵花,每朵花有三个属性:花形(s).颜色(c).气味(m),又三个整数表示.现要对每朵花评级,一朵花的级别是它拥有的美丽能超过的花的数量.定义一朵花A比另一朵花B要美丽,当且仅当Sa&g ...
- 【牛客小白月赛6】F 发电 - 树状数组&快速幂&逆元
题目地址:https://www.nowcoder.com/acm/contest/136/F 树状数组.快速幂.逆元的模板运用: #include<iostream> #include& ...
- HH的项链题解(离线思想+链表+树状数组)
本人第一篇博客重磅推出!!! 希望各位朋友以后多多捧场也多给写意见(我个人喜欢把题解写得啰嗦一点,因为这样方便理解,各位巨佬勿喷) 来讲一道提高+/省选-的骚题:HH的项链(这个HH你理解成皇后呵呵哈 ...
- 树状数组求第k小的元素
int find_kth(int k) { int ans = 0,cnt = 0; for (int i = 20;i >= 0;i--) //这里的20适当的取值,与MAX_VAL有关,一般 ...
- POJ 1990 MooFest(树状数组)
MooFest Time Limit: 1000MS Mem ...
- HDU 2689Sort it 树状数组 逆序对
Sort it Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Sub ...
随机推荐
- php对象(继承,多态)
/2.继承//function abc(){// $arr = func_get_args();//}//子类只能有一个父类 一个父类 可以有多个子类//override 重写//overlood 重 ...
- 0元免费领《JAVA日志》教程,天啦噜!
天啦,老码疯了!辛辛苦苦,费心费力准备的<java日志实战及解析>教程真的不要钱了吗? 作为添物网的小编,每天看着老码为了给大家录制课程,加班加点的做课件,为了保证课程的质量,老码一遍又一 ...
- hust训练赛20160330--B - 又见LKity
Problem 2122 又见LKity Time Limit: 1000 mSec Memory Limit : 32768 KB Problem Description 嗨!大家好,在Templ ...
- 虚拟机(Virtual Machine)和容器(Container)的对比
目前云计算平台常用的虚拟化技术有虚拟机(Virtual Machine)和容器(Container)两种.虚拟机已经是比较成熟的技术,容器技术作为下一代虚拟化技术,国内的各厂商应用还不广,但似乎其代表 ...
- rsync 同步文件重复拷贝问题
rsync 是同步文件的利器,一般用于多个机器之间的文件同步与备份,同时也支持在本地的不同目录之间互相同步文件.在这种场景下,rsync 远比 cp 命令更加合适,它只会同步需要更新的文件,默认情况下 ...
- [luoguP2420] 让我们异或吧(dfs + 异或的性质)
传送门 因为异或满足结合律和交换律. a^b^b=a 所以这个题直接求根节点到每个点路径上的异或值. 对于每组询问直接输出根到两个点的异或值的异或的值. ——代码 #include <cstdi ...
- 最近切的两题SCC的tarjan POJ1236 POJ2186
两题都是水题,1236第一问求缩点后入度为0的点数,第二问即至少添加多少条边使全图强连通,属于经典做法,具体可以看白书 POJ2186即求缩点后出度为0的那个唯一的点所包含的点数(即SCC里有多少点) ...
- [转]制作一个64M的U盘启动盘(mini linux + winpe +dos toolbox)
自己动手定制winpe+各类dos工具箱U盘启动盘+minilinux 由于一个64M老U盘,没什么用,拿来发挥余热.如果U盘够大,可以使用功能更强大的mini linux和带更多工具的winpe.这 ...
- 前端学习之- Ajax
Ajax:页面不做刷新,直接将数据悄悄提交到后台,然后通过回调函数处理返回结果. $.Ajax({ # 提交到后台 url:'/host', # 提交到哪里 type:'POST' # 提交方式 da ...
- 洛谷 P4720 【模板】扩展 / 卢卡斯 模板题
扩展卢卡斯定理 : https://www.luogu.org/problemnew/show/P4720 卢卡斯定理:https://www.luogu.org/problemnew/show/P3 ...