標籤:txt air line space with 增加 dfs序 一個 scanf
原題連結
題意:
給你一個n個節點的樹,每個節點上一開始都有一個蘋果,現在有兩種操作:
Q x :查詢 x 節點以及它的子樹上一共有多少蘋果;
C x :若 x 節點上沒有蘋果,則增加一個,反之,則減少一個;
思路:
這是一個區間查詢,單點修改的問題,我們就會想到用樹狀數組來做,但是怎麼去維護樹上的區間又是一個問題;
於是想到了用 dfs序 ,記錄每一個節點的 left 和 right 也就轉化成了區間問題;
1 /* 2 * @Author: windystreet 3 * @Date: 2018-08-02 22:10:44 4 * @Last Modified by: windystreet 5 * @Last Modified time: 2018-08-02 22:56:03 6 */ 7 #include<stdio.h> 8 #include<string.h> 9 #include<algorithm>10 #include<vector>11 12 using namespace std;13 14 #define X first15 #define Y second16 #define eps 1e-217 #define gcd __gcd18 #define pb push_back19 #define PI acos(-1.0)20 #define lowbit(x) (x)&(-x)21 #define bug printf("!!!!!\n");22 #define mem(x,y) memset(x,y,sizeof(x))23 24 typedef long long LL;25 typedef long double LD;26 typedef pair<int,int> pii;27 typedef unsigned long long uLL;28 29 const int maxn = 1e5+7;30 const LL INF = 1<<30;31 const int mod = 1e9+7;32 typedef vector<int> Ve;33 vector<Ve>G(maxn);34 int left[maxn],right[maxn],cnt=1,n;35 int tree[maxn],vis[maxn];36 37 int query(int x){38 int res = 0;39 while(x){40 res+=tree[x];41 x-=lowbit(x);42 }43 return res;44 }45 void add(int x,int v){46 for(int i=x;i<=n;i+=lowbit(i)){47 tree[i]+=v;48 }49 return ;50 }51 void dfs(int x){52 left[x] = cnt; // 記錄左端點的id53 int sz = G[x].size();54 for(int i=0;i<sz;i++){55 cnt++;56 dfs(G[x][i]);57 }58 right[x]=cnt; // 記錄右端點的id59 }60 61 void solve()62 {63 cnt = 1;64 int x,y,m;65 char op[3];66 for(int i=0;i<=n;i++){tree[i]=0;vis[i]=1;G[i].clear();}67 for(int i=1;i<n;i++){68 scanf("%d%d",&x,&y);69 G[x].pb(y); // 存圖70 }71 dfs(1); // dfs序72 for(int i=1;i<=n;i++){73 add(i,1); // 每個點一開始都有一個蘋果74 }75 scanf("%d",&m);76 for(int i=0;i<m;i++){77 scanf("%s%d",op,&x);78 if(op[0]==‘Q‘){ // 區間查詢79 printf("%d\n",query(right[x])-query(left[x]-1));80 }else{81 if(vis[x])add(left[x],-1); // 單點修改82 else add(left[x],1);83 vis[x]=!vis[x]; // 取反84 }85 }86 return ;87 }88 89 int main()90 {91 // freopen("in.txt","r",stdin);92 // freopen("out.txt","w",stdout);93 // ios::sync_with_stdio(false);94 while(scanf("%d",&n)!=EOF){95 // printf("Case %d: ",cas++);96 solve();97 }98 return 0;99 }
POJ - 3321 Apple Tree(樹狀數組)