poj 3321

来源:互联网 发布:lol赌博软件 编辑:程序博客网 时间:2024/05/22 03:30

在看线段树的时候,看到有一题可以用线段树做的,想不到,刚刚开始时理解错误,以为是二叉树,采用类似并查集的方法,想不到开始一直

tle,优化后就变成一直错误,上网搜索了一下,看了一些代码,和解释发现自己理解错误,可以使任意的树;先编号,再用树状数组,保证在任意子树下,都占用树状数组的一段,写完后,发现用C++超时,就改用了C。

#include<stdio.h>#include<string.h>#include<stdlib.h>#define maxn 100010struct node{int sub;struct node *next;};struct node T[maxn];int a[maxn],b[maxn],c[maxn],start[maxn],end[maxn];int num=1;void dfs(int i){struct node *q=T[i].next;start[i]=num;while(q){dfs(q->sub);q=q->next;num++;}end[i]=num;a[i]=num;}int lowbit(int x){return x&(x^(x-1));}void add(int p,int n){while(p<=n){c[p]++;p+=lowbit(p);}}void reduce(int p,int n){while(p<=n){c[p]--;p+=lowbit(p);}}int sum(int p){int ret=0;while(p){ret+=c[p];p-=lowbit(p);}return ret;}int main(){int i,j,k,n,m;char ch;struct node *p;scanf("%d",&n);for(k=0;k<=n;k++)T[k].next=NULL,b[k]=1;for(k=0;k<n-1;k++){scanf("%d%d",&i,&j);p=(struct node*)malloc(sizeof(struct node));p->sub=j;p->next=T[i].next;T[i].next=p;}dfs(1);for(k=0;k<=n;k++)c[k]=lowbit(k);scanf("%d",&m);for(k=0;k<m;k++){getchar();scanf("%c%d",&ch,&i);if(ch=='C'){if(b[i]) reduce(a[i],n);else add(a[i],n);b[i]=!b[i];}elseprintf("%d\n",sum(end[i])-sum(start[i]-1));}return 0;}


 

 

原创粉丝点击