链式前向星+Poj3321
参考博客:https://blog.csdn.net/acdreamers/article/details/16902023
/*
其中edge[i].to表示第i条边的终点,edge[i].next表示与第i条边同起点的下一条边的存储位置,edge[i].w为边权值.
另外还有一个数组head[],它是用来表示以i为起点的第一条边存储的位置,实际上你会发现这里的第一条边存储的位置其实
在以i为起点的所有边的最后输入的那个编号.
head[]数组一般初始化为-1,对于加边的add函数是这样的:
*/
void add(int u,int v,int w)
{
edge[cnt].w = w;
edge[cnt].to = v;
edge[cnt].next = head[u];
head[u] = cnt++;
}
poj3321
题目是简单题,就是我本人和poj不是很合得来。
1.用到的知识点是dfs序+树状数组
2.开vector会tle,改链式前向星,忘了怎么写,见上面。
3.我的O(n)建BIT数组被卡了,tle
#include<iostream>
#include <cstdio>
#include <fstream>
#include <algorithm>
#include <cmath>
#include <deque>
#include <vector>
#include <queue>
#include <string>
#include <cstring>
#include <map>
#include <stack>
#include <set>
using namespace std;
#define debug(x) cout<<#x<<':'<<x<<endl;
int n,u,v,q;
const int maxn=1e5+100;
//vector<int>G[maxn];
struct node {
int to,nxt;
}edge[maxn<<2];
int tot=0,head[maxn];
void addedge(int u,int v){
++tot;
edge[tot].to=v;
edge[tot].nxt=head[u];
head[u]=tot;
}
long long a[maxn],t[maxn];
namespace BIT
{
long long lowbit(long long x){return x&-x;}
// void init(long long N)//tricks,o(n)建树// 这个时候把n的大小传进来
// {
// // n=N;
// // memset(t,0,sizeof(t));
// for(long long i=1;i<=n;i++){
// t[i]+=a[i];
// int j=i+lowbit(i);//向它最近的父亲更新
// if(j<=n)t[j]+=t[i];
// }
// }
void add(long long x,long long k)//x位置加k
{
//a[x]+=k;
while(x<=n){
t[x]+=k;
x+=lowbit(x);
}
}
long long getsum(long long l,long long r) //闭区间使用[l,r],区间和
{
l--;
long long ansl=0,ansr=0;
while(l)
{
ansl+=t[l];
l-=lowbit(l);
}
while(r)
{
ansr+=t[r];
r-=lowbit(r);
}
return ansr-ansl;
}
}using namespace BIT;
int ls[maxn],rs[maxn],cnt;
void dfs(int root,int b){
ls[root]=++cnt;
for(int i=head[root];i!=-1;i=edge[i].nxt){
if(edge[i].to==b) continue;
dfs(edge[i].to,root);
}
rs[root]=cnt;
}
int main(){
int cnt=0;
memset(head,-1,sizeof(head));
scanf("%d",&n);
for(int i=1;i<n;i++){
scanf("%d%d",&u,&v);
addedge(v,u);addedge(u,v);
}
for(int i=1;i<=n;i++) a[i]=1;
//init(n);
dfs(1,0);
scanf("%d",&q);
char op;int temp;
while(q--){
scanf("
%c %d",&op,&temp);
if(op=='C') {
if(a[ls[temp]]==1)a[ls[temp]]=0,add(ls[temp],-1);
else a[ls[temp]]=1,add(ls[temp],1);
}
else printf("%lld
",getsum(ls[temp],rs[temp])+rs[temp]-ls[temp]+1);
}
system("pause");
}