您的位置:首页 > 移动开发

poj3321 Apple Tree

2016-07-25 09:11 447 查看
dfs搜索记录每个节点的dfs序l,以及其子节点最大的dfs序r,dfs序在区间[l,r]之间的就是dfs序为l的节点的子孙节点。查询节点P的果实个数,即使查询P对应的dfs序区间的和。

要把用树状数组维护的区间上的某一点改为num,可以先记录每个位置的值,计算出增量,再update。

有点坑的是卡vector,TLE

#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<cmath>
#include<algorithm>
#include<queue>
#include<vector>
#define LL long long
#define maxn 110000
#define maxm 110000
using namespace std;

//vector<int>head[maxn];//超时
typedef vector<int>ve;
vector<ve>head(maxn);//1300MS
struct VOL
{
int l,r;
void set(int l,int r){this->l=l,this->r=r;}
}_hash[maxn];
int depth;
bool vis[maxn];
void dfs(int st)
{
int ldep=depth;
vector<int>&vec=head[st];
for(int i=0,len=vec.size();i<len;++i)
{
if(!vis[vec[i]])
{
depth++;
vis[vec[i]]=true;
dfs(vec[i]);
}
}
int rdep=depth;
_hash[st].set(ldep,rdep);
}
int tree[maxn];
int lowbit(int t)
{
return t&(-t);
}
int getsum(int end)
{
int sum=0;
while(end>0)
{
sum+=tree[end];
end-=lowbit(end);
}
return sum;
}
void update(int pos,int num,int n)
{
while(pos<=n)
{
tree[pos]+=num;
pos+=lowbit(pos);
}
return ;
}
int get(int pos)
{
return getsum(pos)-getsum(pos-1);
}
int main()
{
int n;
scanf("%d",&n);
for(int i=1;i<n;++i)
{
int a,b;
scanf("%d%d",&a,&b);
head[a].push_back(b);
head[b].push_back(a);
}
depth=1;
memset(vis,false,sizeof(vis));
vis[1]=true;
dfs(1);
memset(tree,0,sizeof(tree));
for(int i=1;i<=n;++i)
{
// cout<<_hash[i].l<<" "<<_hash[i].r<<endl;
update(i,1,n);
}
int m,pos;
scanf("%d",&m);
char op[10];
memset(vis,false,sizeof(vis));
for(int i=0;i<m;++i)
{
scanf("%s%d",op,&pos);
if(op[0]=='Q')
printf("%d\n",getsum(_hash[pos].r)-getsum(_hash[pos].l-1));
else
{
if(get(_hash[pos].l)==1)
update(_hash[pos].l,-1,n);
else
update(_hash[pos].l,1,n);
}
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: