您的位置:首页 > 大数据 > 人工智能

HDU 3974 Assign the task 2011 Multi-University Training Contest 14 - Host by FZU 线段树

2011-08-27 18:41 603 查看
/*
题意:给定点的上下级关系,规定如果给i分配任务a,那么它所有的下属(直接或间接)都得放弃手上任务开始进行任务a
给你一个序列,T a b,把任务b分配给a节点,C a 查询a正在进行的任务。

非常经典的线段树题目
从树的根节点向下递归并对每个节点i按序编号为level[i].l,在遍历完所有i的子节点后记录i的编号最多子节点的编号为level[i].r
此时level[i].l到level[i].r区间就是点i的覆盖区域(自身加所有子节点),给i分配任务就相当于对[level[i].l,level[i].r]操作
这就可以用线段树处理了

对于线段书某一个节点,用V记录它当前的任务,如果V==-1表示当前没有任务,对于查询a正在进行的任务,从根节点一直往下找,若
查询过程中有节点i的区间覆盖a控制的区间并V>-1,这个任务就是要找的任务,因为i释放V后必定覆盖a的区间,现在V没有释放,表示V的
子节点没有分配新的任务,所以V就是最新的任务

*/
#include <algorithm>
#include <iostream>
#include <cstdio>
#include<vector>
#include <cstring>
using namespace std;
const int N=50005;
int n,m,index;
int out
;
struct Node
{
int L,R,V;//区间的左端点和右端点及分配的任务
}nod[8*N];
void create(int t,int L,int R)//建树过程
{
nod[t].L=L;
nod[t].R=R;
nod[t].V=-1;
int mid=(L+R)>>1;
if(L<R)
{
create(2*t,L,mid);
create(2*t+1,mid+1,R);
}
}
void down(int t)//向下释放任务
{
if(nod[t].V==-1)return ;
nod[2*t].V=nod[2*t+1].V=nod[t].V;
nod[t].V=-1;
}
void insert(int t,int L,int R,int v)
{
//cout<<"tt";
int mid=(nod[t].L+nod[t].R)>>1;
if(nod[t].L==L&&nod[t].R==R)
{
nod[t].V=v;
return ;
}
down(t);
if(R<=mid)insert(2*t,L,R,v);
else if(L>mid)insert(2*t+1,L,R,v);
else {insert(2*t,L,mid,v);insert(2*t+1,mid+1,R,v);}
}
int query(int t,int L)
{

int mid=(nod[t].L+nod[t].R)>>1;
if(nod[t].V>-1||(nod[t].L==nod[t].R))
{
return nod[t].V;
}
down(t);
if(L<=mid)return query(2*t,L);
else return query(2*t+1,L);
}
struct Level
{
int l,r;
}level
;
vector<int> node
;
void dfs(int x)
{
index++;
level[x].l=index;
int size=node[x].size();
for(int i=0;i<size;i++)
{
dfs(node[x][i]);
}
level[x].r=index;
}
void init()
{
scanf("%d",&n);
index=0;
int a,b;
for(int i=0;i<=n;i++)
{node[i].clear();
out[i]=0;}
for(int i=0;i<n-1;i++)
{
scanf("%d%d",&a,&b);
out[a]++;
node[b].push_back(a);
}
for(int i=1;i<=n;i++)
if(out[i]==0)
{
dfs(i);
break;
}
//cout<<index<<endl;
}
void solve(int ca)
{
printf("Case #%d:\n",ca);
//cout<<index<<endl;
create(1,1,index);
scanf("%d",&m);
char s[2];
int a,b;
while(m--)
{
scanf("%s%d",s,&a);
if(s[0]=='C')
{
printf("%d\n",query(1,level[a].l));
}
else
{
scanf("%d",&b);
insert(1,level[a].l,level[a].r,b);
}
}
}
int main()
{
int ca;
scanf("%d",&ca);
for(int i=1;i<=ca;i++)
{
init();
solve(i);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐