刚看到是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(线段树+离散化)的更多相关文章

  1. HDU 3333 Turing Tree 线段树+离线处理

    题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=3333 Turing Tree Time Limit: 6000/3000 MS (Java/Othe ...

  2. HDU 3333 Turing Tree (线段树)

    Turing Tree Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Tota ...

  3. SPOJ D-query && HDU 3333 Turing Tree (线段树 && 区间不相同数个数or和 && 离线处理)

    题意 : 给出一段n个数的序列,接下来给出m个询问,询问的内容SPOJ是(L, R)这个区间内不同的数的个数,HDU是不同数的和 分析 : 一个经典的问题,思路是将所有问询区间存起来,然后按右端点排序 ...

  4. HDU 3333 Turing Tree(树状数组/主席树)

    题意 给定一个长度为 \(n​\) 的序列,\(m​\) 个查询,每次查询区间 \([L,R]​\) 范围内不同元素的和. \(1\leq T \leq 10\) \(1 \leq n\leq 300 ...

  5. HDU 3333 Turing Tree (主席树)

    题意:给定上一个序列,然后有一些询问,求区间 l - r 中有多少个不同的数的和. 析:和求区间不同数的方法是一样,只要用主席树维护就好. 代码如下: #pragma comment(linker, ...

  6. hdu 3333 Turing Tree 图灵树(线段树 + 二分离散)

    http://acm.hdu.edu.cn/showproblem.php?pid=3333 Turing Tree Time Limit: 6000/3000 MS (Java/Others)    ...

  7. HDU 3333 Turing Tree 离线 线段树/树状数组 区间求和单点修改

    题意: 给一个数列,一些询问,问你$[l,r]$之间不同的数字之和 题解: 11年多校的题,现在属于"人尽皆知傻逼题" 核心思想在于: 对于一个询问$[x,R]$ 无论$x$是什么 ...

  8. HDU 3333 Turing Tree(离线树状数组)

    Turing Tree Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Tota ...

  9. HDU - 1542 扫描线入门+线段树离散化

    扫描线算法+线段树维护简介: 像这种求面积的并集的题目,就适合用扫描线算法解决,具体来说就是这样 类似这种给出点的矩形的对角的点的坐标,然后求出所有矩形面积的交集的问题,可以采用扫描线算法解决.图如下 ...

随机推荐

  1. 日积月累系列之分页控件(js源码)

    最近开发了一款分页控件,分享给大家. 主要功能和界面介绍 cform分页控件支持服务端分页.客户端分页.数据过滤.数据排序等功能. 源码介绍 cform-pager分页控件主要由三部分组成:css.s ...

  2. SSM 使用方法

    System Safety Monitor(以下简称为SSM),它是一款俄罗斯出品的系统监控软件,通过监视系统特定的文件(如注册表等)及应用程序,达到保护系统安全的目的.在某些功能上比Winpatro ...

  3. 让低版本的IE浏览器 强制渲染为IE8 或者 以上 浏览器模式

    让低版本的IE浏览器 强制渲染为IE8 或者 以上 浏览器模式 那么就要用下面的方法:让网页兼容ie9 复制代码 代码如下: <!–[if lte IE 8]> <meta http ...

  4. SQL点滴26—常见T-SQL面试解析

    原文:SQL点滴26-常见T-SQL面试解析 它山之石可以攻玉,这一篇是读别人的博客后写下的,不是原原本本的转载,加入了自己的分析过程和演练.sql语句可以解决很多的复杂业务,避免过多的项目代码,下面 ...

  5. June本地环境搭建

    python-china.org论坛使用的June程序就是这货了,使用了Python Flask + SQLite + Node.js 的轻论坛,以后就打算拿这个学习了,如果可能,进行二次开发. Gi ...

  6. .NET 开源了,Visual Studio 开始支持 Android 和 iOS 程序编写并自带 Android 模拟器

    .NET 开源了,Visual Studio 开始支持 Android 和 iOS 程序编写并自带 Android 模拟器 北京时间今天凌晨的 Connect(); 大会上,多少程序员的假想成为现实. ...

  7. 读书笔记—CLR via C#章节11-13

    前言 这本书这几年零零散散读过两三遍了,作为经典书籍,应该重复读反复读,既然我现在开始写博了,我也准备把以前觉得经典的好书重读细读一遍,并且将笔记整理到博客中,好记性不如烂笔头,同时也在写的过程中也可 ...

  8. html5 canvas+js实现ps钢笔抠图

    html5 canvas+js实现ps钢笔抠图 1. 项目要求需要用js实现photoshop中钢笔抠图功能,就用了近三四天的时间去解决它,最终还是基本上把他实现了. 做的过程中走了不少弯路,最终一同 ...

  9. Toad for Oracle的安装

    分享一下Oracle 10gToad for Oracle的安装步骤   三年前用过Oracle,单纯的“用过”,主要就是说对数据库的一些操作,还不包含创建一些存储过程之类的,所以对Oracle仅仅只 ...

  10. VS2010生成安装包制作步骤

    VS2010生成安装包制作步骤   在VS2010中文旗舰版本中生成winForm安装包,可以复制你电脑中的开发环境,避免你忘记了一下配置然后在别的机器上运行不起来.也省去了Framwork的安装. ...