hdu 3333 Turing Tree(线段树+离散化)
刚看到是3xian大牛的题就让我菊花一紧,觉着这题肯定各种高端大气上档次,结果果然没让我失望。
刚开始我以为是一个普通的线段树区间求和,然后啪啪啪代码敲完测试没通过,才注意到这个求和是要去掉相同的值的。
前两天我在做一道题的时候,也是因为数据范围太大(同样是1000000000)不能打表,当时想了许久,想到把这些数值存进一个数组里面,对这个数组进行排序,然后对于其中的某个值可以进行二分查找。今天我又长姿势了,原来这种方法叫做离散化。
刚开始我想着可以把那些相同的值用0去替代,但是一个解决不了的问题是如果把两个相同的值其中一个改为0,那么如果问题区间刚好包含这个值不包含另一个值该怎么处理,甚至如果问题区间问的就是这个值,那该怎么办。
苦思良久也没想到什么好办法。看了下别人的思路,是将所有的问题区间放在一起,以区间的右边界为关键字进行排序,然后对于线段树的值边插入边更新,具体思路见代码。
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#define N 100005
#define M 30005
struct node
{
int x,y;
int id;
}Q[N];
struct tree
{
int x,y;
__int64 sum;
}a[M*3];
int cmp(const void *a,const void *b)
{
return *(int *)a-*(int *)b;
}
int cmp1(const void *a,const void *b)
{
node *c;
node *d;
c=(node *)a;
d=(node *)b;
return c->y-d->y;
}
int visit[M],temp[M],tem[M],b[M];
__int64 ans[N];
void CreatTree(int t,int x,int y)
{
a[t].x=x;
a[t].y=y;
a[t].sum=0;
if(x==y)
return ;
int temp=t*2;
int mid=(x+y)/2;
CreatTree(temp,x,mid);
CreatTree(temp+1,mid+1,y);
return ;
}
void InsertTree(int t,int x,int y)
{
if(a[t].x==a[t].y)
{
a[t].sum+=y;
return ;
}
int temp=t*2;
int mid=(a[t].x+a[t].y)/2;
if(x<=mid)
InsertTree(temp,x,y);
else
InsertTree(temp+1,x,y);
a[t].sum=a[temp].sum+a[temp+1].sum;
return ;
}
__int64 FindTree(int t,int x,int y)
{
if(a[t].x==x&&a[t].y==y)
return a[t].sum;
int temp=t*2;
int mid=(a[t].x+a[t].y)/2;
__int64 sum;
sum=0;
if(y<=mid)
sum+=FindTree(temp,x,y);
else if(x>mid)
sum+=FindTree(temp+1,x,y);
else
{
sum+=FindTree(temp,x,mid);
sum+=FindTree(temp+1,mid+1,y);
}
return sum;
}
int Find(int x,int k)
{
int l,r,mid;
l=1;
r=k;
while(l<=r)
{
mid=(l+r)/2;
if(temp[mid]>x)
r=mid-1;
else if(temp[mid]<x)
l=mid+1;
else
return mid;
}
return 0;
}
int main()
{
int T;
scanf("%d",&T);
while(T--)
{
int n;
scanf("%d",&n);
CreatTree(1,1,n);
int i,j,k;
j=0;
for(i=1;i<=n;i++)
{
scanf("%d",&b[i]);
tem[j++]=b[i];
}
qsort(tem,j,sizeof(tem[0]),cmp);
k=0;
temp[0]=tem[0];
for(i=1;i<j;i++)
{
if(tem[i]!=temp[k])
{
k++;
temp[k]=tem[i];
}
}
memset(visit,0,sizeof(visit));
int m;
scanf("%d",&m);
for(i=1;i<=m;i++)
{
scanf("%d%d",&Q[i].x,&Q[i].y);
Q[i].id=i;
}
qsort(Q+1,m,sizeof(Q[0]),cmp1);
j=1;
for(i=1;i<=n;i++)
{
int flag;
int id;
id=Find(b[i],k);
flag=visit[id];
if(flag)
InsertTree(1,flag,-b[i]);
InsertTree(1,i,b[i]);
visit[id]=i;
for(;j<=m;j++)
{
if(i==Q[j].y)
{
__int64 tt;
tt=FindTree(1,Q[j].x,Q[j].y);
ans[Q[j].id]=tt;
}
else
break;
}
}
for(i=1;i<=m;i++)
printf("%I64d\n",ans[i]);
}
return 0;
}
hdu 3333 Turing Tree(线段树+离散化)的更多相关文章
- HDU 3333 Turing Tree 线段树+离线处理
题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=3333 Turing Tree Time Limit: 6000/3000 MS (Java/Othe ...
- HDU 3333 Turing Tree (线段树)
Turing Tree Time Limit: 6000/3000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Tota ...
- SPOJ D-query && HDU 3333 Turing Tree (线段树 && 区间不相同数个数or和 && 离线处理)
题意 : 给出一段n个数的序列,接下来给出m个询问,询问的内容SPOJ是(L, R)这个区间内不同的数的个数,HDU是不同数的和 分析 : 一个经典的问题,思路是将所有问询区间存起来,然后按右端点排序 ...
- HDU 3333 Turing Tree(树状数组/主席树)
题意 给定一个长度为 \(n\) 的序列,\(m\) 个查询,每次查询区间 \([L,R]\) 范围内不同元素的和. \(1\leq T \leq 10\) \(1 \leq n\leq 300 ...
- HDU 3333 Turing Tree (主席树)
题意:给定上一个序列,然后有一些询问,求区间 l - r 中有多少个不同的数的和. 析:和求区间不同数的方法是一样,只要用主席树维护就好. 代码如下: #pragma comment(linker, ...
- hdu 3333 Turing Tree 图灵树(线段树 + 二分离散)
http://acm.hdu.edu.cn/showproblem.php?pid=3333 Turing Tree Time Limit: 6000/3000 MS (Java/Others) ...
- HDU 3333 Turing Tree 离线 线段树/树状数组 区间求和单点修改
题意: 给一个数列,一些询问,问你$[l,r]$之间不同的数字之和 题解: 11年多校的题,现在属于"人尽皆知傻逼题" 核心思想在于: 对于一个询问$[x,R]$ 无论$x$是什么 ...
- HDU 3333 Turing Tree(离线树状数组)
Turing Tree Time Limit: 6000/3000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Tota ...
- HDU - 1542 扫描线入门+线段树离散化
扫描线算法+线段树维护简介: 像这种求面积的并集的题目,就适合用扫描线算法解决,具体来说就是这样 类似这种给出点的矩形的对角的点的坐标,然后求出所有矩形面积的交集的问题,可以采用扫描线算法解决.图如下 ...
随机推荐
- 高速掌握sinox2014激动人心的ZFS和RAID技术
Sinox2014引入激动人心的zfs系统以及其支持的RAID,让用户高速打造便宜的高可靠性文件server. ZFS文件系统的英文名称为Zettabyte File System,也叫动态文件系统( ...
- Cocos2d-x Lua 阅读Csv文件,使用数据更方便
在我的书或出售之前,我的源代码,有Csvshadow文件. 也许这是偏见.我与工作将是最长的轮廓Csv,所以,我会帮助不大喜欢它的游戏. Csv文件,非常格式easy,也就是说,一个数据线,字段之间用 ...
- Android使用OpenGL ES2.0显示YUV,您的手机上的数据要解决两个方面的坐标
如果说 ,我不知道,如果你不明白这个话题.连接到:http://blog.csdn.net/wangchenggggdn/article/details/8896453(下称链接①), 里面评论有非常 ...
- PHP中遍历stdclass object 及 json
原文:PHP中遍历stdclass object 及 json (从网上找的模拟实例)需要操作的数据: $test=Array ( [0] => stdClass Object ( [tags] ...
- Spring之SpringMVC的Controller(源码)分析
说明: 例子就不举了,还是直接进入主题,本文主要是以SpringMVC的Controller接口为入点,来分析SpringMVC中C的具体实现和处理过程. 1.Controller接口 public ...
- OpenSUSE13.2安装MongoDB
真是一个悲伤的故事,就是你解决过得问题没有记住,却需要再通过搜索引擎来找一遍,幸运的是曾经你做过记录,搜索帮你找到了. 这是我一个Wordpress博客整理记录的,好久没在那里更新了,两个月的时间,我 ...
- 探秘IntelliJ IDEA 13中的版本控制——Subversion 1.8
IntelliJ IDEA 中引入的重要特性就是版本控制,而在IntelliJ IDEA 13中的体现便是支持最新的Subversion 1.8. 相对于之前版本对Subversion的支持,Subv ...
- SQL SERVER – Import CSV File Into SQL Server Using Bulk Insert – Load Comma Delimited File Into SQL Server
CSV stands for Comma Separated Values, sometimes also called Comma Delimited Values. Create TestTabl ...
- 学习html5的WebSocket连接
1.什么是WebSocket WebSocket 是一种自然的全双工.双向.单套接字连接.使用WebSocket,你的HTTP 请求变成打开WebSocket 连接(WebSocket 或者WebSo ...
- ASP.NET DataTable的操作大全
DataTable表示一个与内存有关的数据表,可以使用工具栏里面的控件拖放来创建和使用,也可以在编写程序过程中根据需要独立创建和使用,最常见的情况是作为DataSet的成员使用,在这种情况下就需要用在 ...