POJ3321 - Apple Tree DFS序 + 线段树或树状数组

Apple Tree:http://poj.org/problem?id=3321

题意:

  告诉你一棵树,每棵树开始每个点上都有一个苹果,有两种操作,一种是计算以x为根的树上有几个苹果,一种是转换x这个点上的苹果,就是有就去掉,没有就加上。

思路:

  先对树求一遍dfs序,每个点保存一个l,r。l是最早到这个点的时间戳,r是这个点子树中的最大时间戳,这样就转化为区间问题,可以用树状数组,或线段树维护区间的和。

#include <algorithm>
#include  <iterator>
#include  <iostream>
#include   <cstring>
#include   <cstdlib>
#include   <iomanip>
#include    <bitset>
#include    <cctype>
#include    <cstdio>
#include    <string>
#include    <vector>
#include     <stack>
#include     <cmath>
#include     <queue>
#include      <list>
#include       <map>
#include       <set>
#include   <cassert>
using namespace std;
//#pragma GCC optimize(3)
//#pragma comment(linker, "/STACK:102400000,102400000")  //c++
// #pragma GCC diagnostic error "-std=c++11"
// #pragma comment(linker, "/stack:200000000")
// #pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
// #pragma GCC optimize("-fdelete-null-pointer-checks,inline-functions-called-once,-funsafe-loop-optimizations,-fexpensive-optimizations,-foptimize-sibling-calls,-ftree-switch-conversion,-finline-small-functions,inline-small-functions,-frerun-cse-after-loop,-fhoist-adjacent-loads,-findirect-inlining,-freorder-functions,no-stack-protector,-fpartial-inlining,-fsched-interblock,-fcse-follow-jumps,-fcse-skip-blocks,-falign-functions,-fstrict-overflow,-fstrict-aliasing,-fschedule-insns2,-ftree-tail-merge,inline-functions,-fschedule-insns,-freorder-blocks,-fwhole-program,-funroll-loops,-fthread-jumps,-fcrossjumping,-fcaller-saves,-fdevirtualize,-falign-labels,-falign-loops,-falign-jumps,unroll-loops,-fsched-spec,-ffast-math,Ofast,inline,-fgcse,-fgcse-lm,-fipa-sra,-ftree-pre,-ftree-vrp,-fpeephole2",3)

#define lson (l , mid , rt << 1)
#define rson (mid + 1 , r , rt << 1 | 1)
#define debug(x) cerr << #x << " = " << x << "\n";
#define pb push_back
#define pq priority_queue
#define max3(a,b,c) max(max(a,b),c)

typedef long long ll;
typedef unsigned long long ull;

typedef pair<ll ,ll > pll;
typedef pair<int ,int > pii;
typedef pair<int,pii> p3;

//priority_queue<int> q;//这是一个大根堆q
//priority_queue<int,vector<int>,greater<int> >q;//这是一个小根堆q
#define fi first
#define se second
//#define endl ‘\n‘

#define OKC ios::sync_with_stdio(false);cin.tie(0)
#define FT(A,B,C) for(int A=B;A <= C;++A)  //用来压行
#define REP(i , j , k)  for(int i = j ; i <  k ; ++i)
//priority_queue<int ,vector<int>, greater<int> >que;

const ll mos = 0x7FFFFFFF;  //2147483647
const ll nmos = 0x80000000;  //-2147483648
const int inf = 0x3f3f3f3f;
const ll inff = 0x3f3f3f3f3f3f3f3f; //18
const int mod = 1e9+7;
const double esp = 1e-8;
const double PI=acos(-1.0);

template<typename T>
inline T read(T&x){
    x=0;int f=0;char ch=getchar();
    while (ch<‘0‘||ch>‘9‘) f|=(ch==‘-‘),ch=getchar();
    while (ch>=‘0‘&&ch<=‘9‘) x=x*10+ch-‘0‘,ch=getchar();
    return x=f?-x:x;
}

/*-----------------------showtime----------------------*/
            const int maxn =  300009;
            struct edge
            {
                int to,nx;
            }e[maxn];
            int h[maxn],all;
            void addedge(int u,int v){
                e[all].to = v;
                e[all].nx = h[u];
                h[u] = all++;
            }
            int sum[maxn],vis[maxn];
            char op[20];
            struct node
            {
                int l,r;
            }a[maxn];
            int tot = 1;
            void dfs(int x,int fa){
                a[x].l = tot;
                for(int i=h[x]; ~i; i = e[i].nx){
                    int v = e[i].to;
                    tot++;
                    if(v!=fa){
                        dfs(v,x);
                    }
                }
                a[x].r = ++tot;
            }
            int lowbit(int x){
                return x&(-x);
            }
            void add(int x,int c){
                while(x < maxn){
                    sum[x] += c;
                    x += lowbit(x);
                }
            }
            int getsum(int x){
                int res = 0;
                while(x>0){
                    res += sum[x];
                    x -= lowbit(x);
                }
                return res;
            }
int main(){
            int n,m,x;
            scanf("%d", &n);
            memset(h,-1,sizeof(h));
            for(int i=1; i<n; i++){
                int u,v;
                scanf("%d%d",&u, &v);
                addedge(u,v);
                addedge(v,u);
            }
            dfs(1,-1);
            for(int i=1; i<=n; i++){
                vis[i] = 1;
                add(a[i].l , 1);
            }
            scanf("%d", &m);
            while(m--){
                scanf("%s%d", op,&x);
                if(op[0] == ‘Q‘){
                    printf("%d\n", getsum(a[x].r) - getsum(a[x].l-1));
                }
                else {
                    if(vis[x] == 1){
                        add(a[x].l,-1);
                        vis[x] = 0;
                    }
                    else {
                        add(a[x].l,1);
                        vis[x] = 1;
                    }
                }
            }
            return 0;
}

POJ 3321

原文地址:https://www.cnblogs.com/ckxkexing/p/9637102.html

时间: 2024-10-09 11:10:10

POJ3321 - Apple Tree DFS序 + 线段树或树状数组的相关文章

[poj3321]Apple Tree(dfs序+树状数组)

Apple Tree Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 26762   Accepted: 7947 Description There is an apple tree outside of kaka's house. Every autumn, a lot of apples will grow in the tree. Kaka likes apple very much, so he has been

【POJ 3321】 Apple Tree (dfs重标号设区间+树状数组求和)

[POJ 3321] Apple Tree (dfs重标号设区间+树状数组求和) Apple Tree Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 21966   Accepted: 6654 Description There is an apple tree outside of kaka's house. Every autumn, a lot of apples will grow in the tree. K

POJ 3321 Apple Tree DFS序 + 树状数组

多次修改一棵树节点的值,或者询问当前这个节点的子树所有节点权值总和. 首先预处理出DFS序L[i]和R[i] 把问题转化为区间查询总和问题.单点修改,区间查询,树状数组即可. 注意修改的时候也要按照dfs序修改,因为你查询就是按照dfs查的,所以修改也要用dfs序修改 L[i]是唯一的. #include <cstdio> #include <cstdlib> #include <cstring> #include <cmath> #include <

codechef T6 Pishty and tree dfs序+线段树

PSHTTR: Pishty 和城堡题目描述 Pishty 是生活在胡斯特市的一个小男孩.胡斯特是胡克兰境内的一个古城,以其中世纪风格 的古堡和非常聪明的熊闻名全国. 胡斯特的镇城之宝是就是这么一座古堡,历史上胡斯特依靠这座古堡抵挡住了疯人国的大军. 对于 Pishty 来说,真正吸引他的是古堡悠长的走廊和高耸的钟楼,以及深藏于其中的秘密-- 古堡可以用一棵 N 个节点的树的描述,树中有 N ?1 条无向边,每条边有一个魔法数字 C. 当一个旅游团参观古堡时,他们会选择树上 U 到 V 的路径游

hdu 6191 Query on A Tree(dfs序+可持久化字典树)

题目链接:hdu 6191 Query on A Tree 题意: 给你一棵树,每个节点有一个值,现在有q个询问,每个询问 询问一个u x,问以u为根的子树中,找一个节点,使得这个节点的值与x异或的值最大,输出那个最大的值. 题解: dfs序和一棵可持久化字典树就搞定了. 1 #include<bits/stdc++.h> 2 #define mst(a,b) memset(a,b,sizeof(a)) 3 #define F(i,a,b) for(int i=a;i<=b;++i) 4

POJ 3321 Apple Tree DFS序+fenwick

题目大意:有一颗长满苹果的苹果树,有两个操作. 1.询问以一个点为根的子树中有多少个苹果. 2.看看一个点有没有苹果,假设没有苹果.那么那里就立即长出一个苹果(= =!):否则就把那个苹果摘下来. 思路:进行一次深搜,将每一个节点最開始出现的时间和最后出现的时间记在一个数组里,那么这两点之间的点就是它以及它的子树的二倍,然后就用树状数组来维护区间和即可了. CODE: #include <cstdio> #include <cstring> #include <iostrea

codeforces 617E. New Year Tree dfs序+线段树+bitset

题目链接 给一棵树, 每个节点有颜色, 两种操作, 一种是将一个节点的子树全都染色成c, 一种是查询一个节点的子树有多少个不同的颜色, c<=60. 每个节点一个bitset维护就可以. #include <iostream> #include <vector> #include <cstdio> #include <cstring> #include <algorithm> #include <cmath> #include

codeforces 343D Water Tree 树链剖分 dfs序 线段树 set

题目链接 这道题主要是要考虑到同一棵子树中dfs序是连续的 然后我就直接上树剖了... 1 #include<bits/stdc++.h> 2 using namespace std; 3 const int MAXN=600005; 4 5 struct Node 6 { 7 int l,r; 8 int value; 9 void init() 10 { 11 l=r=value=0; 12 } 13 }tree[4*MAXN]; 14 vector<int>nei[MAXN]

HDOJ5692解题报告【dfs序+线段树】

题目地址: http://acm.hdu.edu.cn/showproblem.php?pid=5692 题目概述: 中文题面就不赘述了. 大致思路: 这个题给出的是一棵树,我们可以使用dfs序将这棵树处理成一条链,然后对这条链来进行信息维护和查询. 有两种操作,0 x是询问从0出发(题目保证0为树根)经过x的路径中的最大权值,1 x y是将点x的权值修改成y,这时我们用线段树来维护一个d[i]表示点i到0点的权值和. 对于第一种操作就是查询x及其子树上的最大值,经过dfs序的处理之后这是一段连