(TSOJ1350~1352)面朝大海,春暖花开
来源:互联网 发布:华北电力大学网络教育 编辑:程序博客网 时间:2024/04/30 14:38
题目描述:
选择那些大晴天的日子,行走在孤单的海岸线,静静地种花给自己看~
我们假设把海岸线分为n块,每块的分别标记为1...n,每块都可以种花,每次种花可以选择某个[left,right]的闭区间,每块种上一朵花.经过m次种花操作后,根据输入的区间,求该区间内花的总数.
输入描述:
多组输入
对每组输入,第一行有两个整数n m,分别代表总块数和种花的次数.(1 <= n, m <= 100)
接下来的m行, 每行两个整数 L,R 代表[L,R]区间内每块种上一朵花.(1 <= L <= R <= n)
最后一行,输入两个整数 a,b 代表最后要查询的花的总数的区间.(1 <= a <= b <= n)
输出描述:
对每组测试数据,输出区间[a,b]内花的总数
{
return x&(-x);
}
先列举出从1~32的lowbit,
1 2 1 4 1 2 1 8 1 2 1 4 1 2 1 16 1 2 1 4 1 2 1 8 1 2 1 4 1 2 1 32
{
for(int i=x;i<=n;i+=lowbit(i))
a[i]++;
}
{
int ans=0;
for(int i=x;i>0;i-=lowbit(i))
ans += a[i];
return ans;
}
{
for(int i=x;i<=n;i+=lowbit(i))
{
c1[i] += num;
c2[i] += num*x;
}
}
int sum(int x)
{
int ans=0;
for(int i=x;i>0;i-=lowbit(i))
{
ans += (x+1)*c1[i]-c2[i];
}
return ans;
}
我们假设sigma(r,i)表示r数组的前i项和,调用一次的复杂度是log2(i)
设原数组是a[n],差分数组c[n],c[i]=a[i]-a[i-1],那么明显地a[i]=sigma(c,i),如果想要修改a[i]到a[j](比如+v),只需令c[i]+=v,c[j+1]-=v。
观察式子:
a[1]+a[2]+...+a[n]
= (c[1]) + (c[1]+c[2]) + ... + (c[1]+c[2]+...+c[n])
= n*c[1] + (n-1)*c[2] +... +c[n]
= n * (c[1]+c[2]+...+c[n]) - (0*c[1]+1*c[2]+...+(n-1)*c[n]) (式子①)
那么我们就维护一个数组c2[n],其中c2[i] = (i-1)*c[i]
每当修改c的时候,就同步修改一下c2,这样复杂度就不会改变
那么
式子①
=n*sigma(c,n) - sigma(c2,n)
于是我们做到了在O(logN)的时间内完成一次区间和查询。
以上即为树状数组的大致题解,其中最为精彩的地方就在于lowbit函数的运用以及差分求前缀和,巧妙地将算法的时间复杂度由O(N)级别降到O(logn)级别。
- (TSOJ1350~1352)面朝大海,春暖花开
- 面朝大海 春暖花开(题)
- 面朝大海,春暖花开(部分引用)
- 面朝大海,春暖花开
- 面朝大海,春暖花开
- 面朝大海 春暖花开
- [转载]面朝大海 春暖花开
- 面朝大海,春暖花开
- 面朝大海,春暖花开
- 面朝大海,春暖花开
- 面朝大海,春暖花开
- 面朝大海,春暖花开
- 面朝大海,春暖花开
- 面朝大海 春暖花开
- 面朝大海 春暖花开
- 面朝大海, 春暖花开
- 面朝大海 春暖花开
- 面朝大海,春暖花开
- 配置文件路径如何写
- Quicksum
- 中断上下文简要概述
- 用 Go 构建一个区块链 -- Part 7: 网络
- 蓝桥杯 入门训练 圆的面积
- (TSOJ1350~1352)面朝大海,春暖花开
- C#初识2 面向对象之封装(set get)
- POJ 3083.Children of the Candy Corn
- 树状数组 ( Binary Indexed Tree,BIT,二分索引树 )
- hdu1698 Just a Hook (线段树)
- UDP和TCP
- 初识Elasticsearch
- QT移植mqtt
- 中断管理之下半部软中断