您的位置:首页 > 其它

HDU_1698 Just a Hook(线段树)

2011-09-16 16:20 211 查看
 

 /*第二次做这题,其中有些坎坷,第一次做时理解的也不深刻,导致这次做起来有些费
劲。开始思路是一边更新一边计算总的Hook值,可惜一直WA,做了大半下午,晕死,先
更新完再统计一遍的方法过了,再后来上网查了一下,正好有个大牛也是用第一种思路做
的,参考了一下他的代码,发现原来我的flag初值整错了。。。。*/

//第一种思路代码(609+ms):

#include <iostream>
#include <cstdio>
#define L(t) t << 1
#define R(t) t << 1 | 1

using namespace std;

const int N = 200005;

struct node
{
int l, r;
int flag;    //标记更新后的hook类型
int hook;    //统计总的hook值
}node[N*4];

void creat(int t, int l, int r)
{
node[t].l = l;
node[t].r = r;
node[t].flag = 0;
if(l == r)
{
node[t].hook = 1;
return;
}
int mid = (l + r) >> 1;

creat(L(t), l, mid);
creat(R(t), mid+1, r);

node[t].hook = node[L(t)].hook + node[R(t)].hook;
}

void updata(int t, int l, int r, int val)
{
if(node[t].l >= l && node[t].r <= r)
{
node[t].hook = (r-l+1)*val;
node[t].flag = val;
return ;
}

int mid = (node[t].l + node[t].r) >> 1;

if(node[t].flag)    //下分flag值和hook值
{
node[L(t)].flag = node[t].flag;
node[L(t)].hook = (mid - node[t].l + 1) * node[t].flag;    //左孩子

node[R(t)].flag = node[t].flag;
node[R(t)].hook = (node[t].r - mid) * node[t].flag;    //右孩子
node[t].flag = 0;
}

if(l > mid)
updata(R(t), l, r, val);
else if(r <= mid)
updata(L(t), l, r, val);
else
{
updata(L(t), l, mid, val);
updata(R(t), mid+1, r, val);
}

node[t].hook = node[L(t)].hook + node[R(t)].hook;
}

int main()
{
//freopen("data.in", "r", stdin);

int cas = 0, n, m, T, x, y, z;
scanf("%d", &T);
while(T--)
{
scanf("%d", &n);
creat(1, 1, n);
scanf("%d", &m);
while(m--)
{
scanf("%d%d%d", &x, &y, &z);
updata(1, x, y, z);
}
printf("Case %d: The total value of the hook is %d.\n", ++cas, node[1].hook);
}
return 0;
}

//第二种思路代码(468+ms):

#include <iostream>
#include <cstdio>
#define L(t) t << 1
#define R(t) t << 1 | 1

using namespace std;

const int N = 200005;

struct node
{
int l, r;
int hook;    //存放当前结点的hook类型
}node[N*4];

int sum;

void creat(int t, int l, int r)
{
node[t].l = l;
node[t].r = r;
node[t].hook = 1;
if(l == r)    return ;

int mid = (l + r) >> 1;
creat(L(t), l, mid);
creat(R(t), mid + 1, r);
}

void updata(int t, int l, int r, int v)
{
if(node[t].l >= l && node[t].r <= r)
{
node[t].hook = v;
return ;
}

if(node[t].hook != -1)
{
node[L(t)].hook = node[t].hook;
node[R(t)].hook = node[t].hook;
node[t].hook = -1;
}

int mid = (node[t].l + node[t].r) >> 1;
if(l > mid)
updata(R(t), l, r, v);
else if(r <= mid)
updata(L(t), l, r, v);
else
{
updata(L(t), l, mid, v);
updata(R(t), mid + 1, r, v);
}
}

void query(int t, int l, int r)    //最后统计
{
if(node[t].hook != -1)
{
sum += node[t].hook * (r - l + 1);
return ;
}
int mid = (node[t].l + node[t].r) >> 1;

query(L(t), l, mid);
query(R(t), mid + 1, r);
}

int main()
{
//freopen("data.in", "r", stdin);

int T, n, m, x, y, z, cas = 0;
scanf("%d", &T);
while(T--)
{
scanf("%d", &n);
creat(1, 1, n);
scanf("%d", &m);
while(m--)
{
scanf("%d%d%d", &x, &y, &z);
updata(1, x, y, z);
}
sum = 0;
query(1, 1, n);
printf("Case %d: The total value of the hook is %d.\n", ++cas, sum);
}
return 0;
}

/*按说第一种思路应该比第二种快的,不知道为什么是这个情况*/
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: