这道题目的数据卡得好厉害。

题目明显是考察线段树延迟标记的,但是因为要考虑到p的值,这种延迟是有条件的:在该节点下所有的数据对于p都应该位于p的同一侧。要么都比p大,要么都比p小。

开始的时候我用一个flag来标记节点下面的值是否相同,这个想法其实不对,在最恶劣的情况下,这种方式几乎会直接退化到单点更新的程度,而且随着数据的输入,算法的效率会越来越低,因为整个树从上到下都是在一次性使用,没办法维护。

但是我还是提交了一下,没有任何悬念的TLE。

我又开始正常的思路,不再考虑一个节点下面的值是否相同,而是去想这些值是否在p的同一侧。想了一下,这样的话,我们只需要知道节点下面的最小值和最大值是不是在p的同一侧就行了,而维护最大值最小值之类的事简直是线段树最擅长的了。代码写好后提交,还是TLE。

这我就有点儿郁闷了,这种方法确实在很高程度上实现了数据的成段更新。我的建树和查找是完全相同的操作,在两个地方不太可能有什么优化的空间,能优化的地方只有更新操作。不过我实在想不来该怎么优化。

我去看了下别人的题解,发现博主用跟我同样地思路过了,不过过得很勉强,在G++下TLE,在C++下AC。我看了下他的代码,相对于我的代码来说,做了两个地方的优化,一个是线段树向下分发的时候加了一个if(a[t].dam)的操作,这个操作能够提高的效率微乎其微。另一个是减少了一个判断操作,这个地方我觉得能提高一些效率。

提交C++928msAC。

#include<stdio.h>
#include<string.h>
#define N 200005
struct node
{
int x,y;
int dam;
int min,max;
}a[N*3];
int b[N];
int m,n,p;
int Max(int x,int y)
{
if(x>y)
return x;
else
return y;
}
int Min(int x,int y)
{
if(x<y)
return x;
else
return y;
}
void CreatTree(int t,int x,int y)
{
a[t].x=x;
a[t].y=y;
a[t].dam=0;
a[t].max=0;
a[t].min=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,int k)
{
if(a[t].x==x&&a[t].y==y)
{
if(a[t].min>=p)
{
a[t].dam+=2*k;
a[t].max+=2*k;
a[t].min+=2*k;
return ;
}
else if(a[t].max<p)
{
a[t].dam+=k;
a[t].min+=k;
a[t].max+=k;
return ;
}
}
int temp=t*2;
int mid=(a[t].x+a[t].y)/2;
if(a[t].dam>0)
{
a[temp].dam+=a[t].dam;
a[temp+1].dam+=a[t].dam;
a[temp].min+=a[t].dam;
a[temp+1].min+=a[t].dam;
a[temp].max+=a[t].dam;
a[temp+1].max+=a[t].dam;
a[t].dam=0;
}
if(y<=mid)
InsertTree(temp,x,y,k);
else if(x>mid)
InsertTree(temp+1,x,y,k);
else
{
InsertTree(temp,x,mid,k);
InsertTree(temp+1,mid+1,y,k);
}
a[t].max=Max(a[temp].max,a[temp+1].max);
a[t].min=Min(a[temp].min,a[temp+1].min);
return ;
}
void FindTree(int t,int x,int y)
{
if(a[t].x==a[t].y)
{
b[a[t].x]=a[t].dam;
//printf("%d %d %d %d %d\n",a[t].x,a[t].y,a[t].dam,a[t].max,a[t].min);
return ;
}
int temp=t*2;
int mid=(a[t].x+a[t].y)/2;
a[temp].dam+=a[t].dam;
a[temp+1].dam+=a[t].dam;
a[t].dam=0;
FindTree(temp,x,mid);
FindTree(temp+1,mid+1,y);
//printf("%d %d %d %d %d\n",a[t].x,a[t].y,a[t].dam,a[t].max,a[t].min);
return ;
}
int main()
{
while(scanf("%d%d%d",&n,&m,&p)!=EOF)
{
CreatTree(1,1,n);
while(m--)
{
int x,y,k;
scanf("%d%d%d",&x,&y,&k);
InsertTree(1,x,y,k);
}
FindTree(1,1,n);
int i;
for(i=1;i<n;i++)
printf("%d ",b[i]);
printf("%d\n",b[i]);
}
return 0;
}

hdu 4107 Gangster(线段树,时间卡得很严)的更多相关文章

  1. hdu 4031 attack 线段树区间更新

    Attack Time Limit: 5000/3000 MS (Java/Others)    Memory Limit: 65768/65768 K (Java/Others)Total Subm ...

  2. HDU 4578 Transformation --线段树,好题

    题意: 给一个序列,初始全为0,然后有4种操作: 1. 给区间[L,R]所有值+c 2.给区间[L,R]所有值乘c 3.设置区间[L,R]所有值为c 4.查询[L,R]的p次方和(1<=p< ...

  3. hdu 4288 离线线段树+间隔求和

    Coder Time Limit: 20000/10000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Su ...

  4. hdu 3016 dp+线段树

    Man Down Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total S ...

  5. HDU 3308 (线段树区间合并)

    http://acm.hdu.edu.cn/showproblem.php?pid=3308 题意: 两个操作  : 1 修改 单点  a 处的值. 2 求出 区间[a,b]内的最长上升子序列. 做法 ...

  6. HDU 4107 Gangster(线段树 特殊懒惰标记)

    两种做法. 第一种:标记区间最大值和最小值,若区间最小值>=P,则本区间+2c,若区间最大值<P,则本区间+c.非常简单的区间更新. 最后发一点牢骚:最后query查一遍就行,我这个2B竟 ...

  7. HDU 4107 Gangster Segment Tree线段树

    这道题也有点新意,就是须要记录最小值段和最大值段,然后成段更新这个段,而不用没点去更新,达到提快速度的目的. 本题过的人非常少,由于大部分都超时了,我严格依照线段树的方法去写.一開始竟然也超时. 然后 ...

  8. HDU 4107 Gangster

    Gangster Time Limit: 1000ms Memory Limit: 32768KB This problem will be judged on HDU. Original ID: 4 ...

  9. HDU 5861 Road 线段树区间更新单点查询

    题目链接: http://acm.split.hdu.edu.cn/showproblem.php?pid=5861 Road Time Limit: 12000/6000 MS (Java/Othe ...

随机推荐

  1. Ionic实战一:Ionic仿照微信项目

    github下载地址:https://github.com/Frogmarch/ionic-wechat 博客学习地址:http://www.cnblogs.com/Frogmarch/ Ionic仿 ...

  2. Logan:美团点评的开源移动端基础日志库

    前言 Logan是美团点评集团移动端基础日志组件,这个名称是Log和An的组合,代表个体日志服务.同时Logan也是“金刚狼”大叔的名号,当然我们更希望这个产品能像金刚狼大叔一样犀利. Logan已经 ...

  3. Highmaps网页图表教程之绘图区显示标签显示数据标签定位

    Highmaps网页图表教程之绘图区显示标签显示数据标签定位 Highmaps数据标签定位 由于数据标签是和节点一一对应,所以数据标签是依据节点位置进行定位的.本节详细讲解如何对数据标签进行定位. H ...

  4. IIS Server Farms入门

    概念了解 IIS Server Farms,实际上应该叫“Microsoft Web Farm Framework (WFF)”,依赖于“Web Platform Installer”才能安装,依赖于 ...

  5. TCP的三次握手与四次释放

    TCP的三次握手与四次释放 一.名词解释     序列号seq:占4个字节,用来标记数据段的顺序,TCP把连接中发送的所有数据字节都编上一个序号,第一个字节的编号由本地随机产生:给字节编上序号后,就给 ...

  6. [BZOJ4850][JSOI2016]灯塔(分块/决策单调性优化DP)

    第一种方法是决策单调性优化DP. 决策单调性是指,设i>j,若在某个位置x(x>i)上,决策i比决策j优,那么在x以后的位置上i都一定比j优. 根号函数是一个典型的具有决策单调性的函数,由 ...

  7. sgu 176 上下界网络流最小可行流带输出方案

    算法步骤: 1. 先将原图像最大可行流那样变换,唯一不同的是不加dst->src那条边来将它变成无源无汇的网络流图.直接跑一边超级源到超级汇的最大流. 2. 加上刚才没有加上的那条边p 3. 再 ...

  8. bzoj 4033

    树形DP,dp[i][j]表示i子树中,选了j个白点,i子树中所有边的贡献. /************************************************************ ...

  9. 【51nod-1239&1244】欧拉函数之和&莫比乌斯函数之和 杜教筛

    题目链接: 1239:http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1239 1244:http://www.51nod. ...

  10. Codeforces Round #281 (Div. 2) A. Vasya and Football 暴力水题

    A. Vasya and Football time limit per test 2 seconds memory limit per test 256 megabytes input standa ...