hdu 3473 裸的划分树
思路:
用Sum[dep][i]记录从tree[po].l到i中进入左子树的和。
#include<iostream>
#include<algorithm>
#include<cstring>
#include<cstdio>
#include<algorithm>
#include<cmath>
#define Maxn 100010
#define inf 0x7fffffff
#define lowbit(x) (x&(-x))
#define lson(x) (x<<1)
#define rson(x) ((x<<1)|1)
#define mid ((tree[po].l+tree[po].r)>>1)
using namespace std;
struct Tree{
int l,r;
}tree[Maxn*];
__int64 Sum[][Maxn],sum[Maxn];
__int64 lnum,lsum;
int sorted[Maxn];
int val[][Maxn],toLeft[][Maxn],n;
void BuildTree(int l,int r,int dep,int po)
{
tree[po].l=l,tree[po].r=r;
if(l==r) return ;
int same=mid-l+,i;
for(i=l;i<=r;i++)
if(val[dep][i]<sorted[mid])
same--;
int lpos=l,rpos=mid+;
for(i=l;i<=r;i++)
{
if(i==l)
toLeft[dep][i]=;
else
toLeft[dep][i]=toLeft[dep][i-];
Sum[dep][i]=Sum[dep][i-];
if(val[dep][i]<sorted[mid])
Sum[dep][i]+=(__int64)val[dep][i],toLeft[dep][i]++,val[dep+][lpos++]=val[dep][i];
else
if(val[dep][i]>sorted[mid])
val[dep+][rpos++]=val[dep][i];
else
if(same)
Sum[dep][i]+=(__int64)val[dep][i],toLeft[dep][i]++,val[dep+][lpos++]=val[dep][i],same--;
else
val[dep+][rpos++]=val[dep][i];
}
BuildTree(l,mid,dep+,lson(po));
BuildTree(mid+,r,dep+,rson(po));
}
int query(int l,int r,int k,int dep,int po)
{
if(l==r)
return val[dep][l];
int vd,invd;
if(l==tree[po].l)
vd=toLeft[dep][r],invd=;
else
vd=toLeft[dep][r]-toLeft[dep][l-],invd=toLeft[dep][l-];
if(vd>=k){
int newl=tree[po].l+invd;
int newr=tree[po].l+vd+invd-;
return query(newl,newr,k,dep+,lson(po));
}
else{
int ss=l-tree[po].l-invd;
int s=r-l+-vd;
int newl=mid+ss+;
int newr=mid+ss+s;
lnum+=vd;
lsum+=Sum[dep][r]-Sum[dep][l-];
return query(newl,newr,k-vd,dep+,rson(po));
}
}
int main()
{
int m,i,j,k,s,t,T,Case=;
scanf("%d",&T);
while(T--)
{
scanf("%d",&n);
for(i=;i<=n;i++)
{
scanf("%d",&val[][i]);
sorted[i]=val[][i];
sum[i]=sum[i-]+(__int64)val[][i];
}
sort(sorted+,sorted++n);
BuildTree(,n,,);
__int64 temp;
__int64 ans=;
scanf("%d",&m);
printf("Case #%d:\n",++Case);
for(i=;i<=m;i++)
{
scanf("%d%d",&s,&t);
s++,t++;
lnum=lsum=;
k=(t-s+)/;
temp=(__int64)query(s,t,k,,);
//cout<<lnum<<" "<<temp<<" "<<lsum<<" "<<sum[t]<<" "<<k<<" "<<sum[s-1]<<endl;
ans=lnum*temp-lsum+sum[t]-sum[s-]-lsum-(t-s+-k)*temp;
printf("%I64d\n",ans);
}
printf("\n");
}
return ;
}
hdu 3473 裸的划分树的更多相关文章
- HDU 3473 Minimum Sum 划分树,数据结构 难度:1
http://acm.hdu.edu.cn/showproblem.php?pid=3473 划分树模板题目,需要注意的是划分树的k是由1开始的 划分树: 参考:http://blog.csdn.ne ...
- HDU 3473 Minimum Sum 划分树
题意: 给出一个长度为\(n(1 \leq n \leq 10^5)\)的序列\(a\) 有若干次查询l r:找到一个\(x\)使得\(\sum \limits_{l \leq i \leq r} \ ...
- hdu 2665 Kth number(划分树模板)
http://acm.hdu.edu.cn/showproblem.php?pid=2665 [ poj 2104 2761 ] 改变一下输入就可以过 http://poj.org/problem? ...
- HDU 2665 Kth number(划分树)
Kth number Time Limit: 15000/5000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total S ...
- HDU 4417 - Super Mario ( 划分树+二分 / 树状数组+离线处理+离散化)
题意:给一个数组,每次询问输出在区间[L,R]之间小于H的数字的个数. 此题可以使用划分树在线解决. 划分树可以快速查询区间第K小个数字.逆向思考,判断小于H的最大的一个数字是区间第几小数,即是答案. ...
- hdu 2665 Kth number_划分树
题意:求区间[a,b]的第k大 因为多次询问要用到划分树 #include <iostream> #include<cstdio> #include<algorithm& ...
- HDU 4417 Super Mario(划分树)
Super Mario Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total ...
- hdu 4417,poj 2104 划分树(模版)归并树(模版)
这次是彻底把划分树搞明确了,与此同一时候发现了模版的重要性.敲代码一个字符都不能错啊~~~ 划分树具体解释:点击打开链接 题意:求一组数列中随意区间不大于h的个数. 这个题的做法是用二分查询 求给定 ...
- HDU 1251 裸的字典树、入门题
裸的字典树还是挺简单的. 四个基本操作建立.查找.插入.删除 建立新结点我是用的c++中 new操作.当然也可以用malloc,都方便 不过指针阿.地址阿.这其中关系什么的我貌似还不是很清楚阿. 因为 ...
随机推荐
- POJ 3660 Cow Contest(传递闭包floyed算法)
Cow Contest Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 5989 Accepted: 3234 Descr ...
- keil中编译时出现*** ERROR L107: ADDRESS SPACE OVERFLOW
解决方法: http://zhidao.baidu.com/link?url=DWTVVdALVqPtUt0sWPURD6c1eEppyu9CXocLTeRZlZlhwHOA1P1xdesqmUQNw ...
- java 字符串String操作工具类
/** * StrKit. */ public class StrKit { /** * 首字母变小写 */ public static String firstCharToLowerCase(Str ...
- Codeforces Round #260 (Div. 1) A. Boredom (简单dp)
题目链接:http://codeforces.com/problemset/problem/455/A 给你n个数,要是其中取一个大小为x的数,那x+1和x-1都不能取了,问你最后取完最大的和是多少. ...
- HDU2066一个人的旅行(dijkstra)
一开始拿到这个题感觉floyd可能会超,还是写了写,果然1WA+1TLE,之后觉得用dijkstra试试看看S和D会不会比较小,还是1WA+1TLE,最后还是借鉴了别人的做法. 把他的家作为起点,与他 ...
- Linux命令行访问网页
找到个好资料,备份行: http://hi.baidu.com/oyvfhp/blog/item/3aa5ced5b40563d351da4bb0.html CURL --- 命令行浏览器 这东西 ...
- struts validate
1 login.jsp方式1 <%@ page language="java" import="java.util.*" pageEncoding=&q ...
- 用python查看URL编码的中文
什么是URL编码呢,请看https://zh.wikipedia.org/wiki/Urlencode. 有时,我们向一些网站提交中文参数时,中文是会被编码成这种格式的 "%B1%E0%C2 ...
- C++ 临时对象
1.什么是临时对象? swap方法中,常常定义一个temp对象,这个temp对象不是临时对象,而是局部对象.这里所说的临时对象是不可见的,在原代码中是看不到的. 2.为什么会产生临时对象? a.客户期 ...
- C#中使用UDP通信
UDP通信是无连接通信,客户端在发送数据前无需与服务器端建立连接,即使服务器端不在线也可以发送,但是不能保证服务器端可以收到数据. 服务器端代码: static void Main(string[] ...