bzoj3631
裸的链剖
1 #include<bits/stdc++.h> 2 #define lowbit(a) ((a)&(-(a))) 3 #define l(a) ((a)<<1) 4 #define r(a) ((a)<<1|1) 5 #define clr(a,x) memset(a,x,sizeof(a)) 6 #define rep(i,l,r) for(int i=l;i<(r);i++) 7 #define Rep(i,a) rep(i,0,e[a].size()) 8 typedef long long ll; 9 using namespace std; 10 int read() 11 { 12 char c=getchar(); 13 int ans=0,f=1; 14 while(!isdigit(c)){ 15 if(c=='-') f=-1; 16 c=getchar(); 17 } 18 while(isdigit(c)){ 19 ans=ans*10+c-'0'; 20 c=getchar(); 21 } 22 return ans*f; 23 } 24 struct node{ 25 int l,r,sum,add; 26 }; 27 const int maxn=300009,inf=0x7fffffff; 28 int n,dfstime=0,a[maxn],w[maxn],dep[maxn],size[maxn],f[maxn],son[maxn],top[maxn],id[maxn],idr[maxn]; 29 node x[maxn<<2]; 30 vector<int>e[maxn]; 31 void dfs(int k){ 32 size[k]=1; 33 Rep(i,k){ 34 int to=e[k][i]; 35 if(f[k]==to) continue; 36 f[to]=k; 37 dep[to]=dep[k]+1; 38 dfs(to); 39 size[k]+=size[to]; 40 if(!son[k]||size[son[k]]<size[to]) son[k]=to; 41 } 42 } 43 int Top; 44 void Dfs(int k){ 45 top[k]=Top; 46 id[k]=++dfstime; 47 idr[id[k]]=k; 48 if(son[k]) Dfs(son[k]); 49 Rep(i,k){ 50 int to=e[k][i]; 51 if(!id[to]) Dfs(Top=to); 52 } 53 } 54 void maintain(int k){ 55 x[k].sum=x[l(k)].sum+x[r(k)].sum; 56 } 57 void pushdown(int k){ 58 if(x[k].l!=x[k].r&&x[k].add){ 59 x[l(k)].add+=x[k].add; 60 x[r(k)].add+=x[k].add; 61 x[l(k)].sum+=(x[l(k)].r-x[l(k)].l+1)*x[k].add; 62 x[r(k)].sum+=(x[r(k)].r-x[r(k)].l+1)*x[k].add; 63 } 64 x[k].add=0; 65 } 66 void modify(int k,int l,int r,int t){ 67 //cout<<k<<' '<<l<<' '<<r<<endl; 68 pushdown(k); 69 if(x[k].l==l&&x[k].r==r){ 70 x[k].add+=t; 71 x[k].sum+=(r-l+1)*t; 72 return; 73 } 74 int mid=(x[k].l+x[k].r)>>1; 75 if(l>mid) modify(r(k),l,r,t); 76 else if(r<=mid) modify(l(k),l,r,t); 77 else{ 78 modify(l(k),l,mid,t); 79 modify(r(k),mid+1,r,t); 80 } 81 maintain(k); 82 } 83 int sum(int k,int u){ 84 pushdown(k); 85 if(x[k].l==x[k].r) return x[k].sum; 86 int mid=(x[k].l+x[k].r)>>1; 87 return sum(u<=mid?l(k):r(k),u); 88 } 89 void build(int k,int l,int r){ 90 x[k].l=l,x[k].r=r,x[k].add=0; 91 if(l==r){ 92 x[k].sum=0; 93 return; 94 } 95 int mid=(l+r)>>1; 96 build(l(k),l,mid); 97 build(r(k),mid+1,r); 98 maintain(k); 99 } 100 void init(){ 101 dfs(1); 102 Dfs(Top=1); 103 build(1,1,n); 104 //cout<<"init ok\n"; 105 //rep(i,1,n<<1|1){ 106 // printf("%d %d %d %d\n",i,x[i].l,x[i].r,x[i].sum); 107 //} 108 } 109 void add(int u,int v,int t){ 110 //cout<<"u&v:"<<u<<' '<<v<<endl; 111 while(top[u]!=top[v]){ 112 if(dep[top[u]]<dep[top[v]]) swap(u,v); 113 modify(1,id[top[u]],id[u],t); 114 u=f[top[u]]; 115 } 116 if(dep[u]>dep[v]) swap(u,v); 117 modify(1,id[u],id[v],t); 118 } 119 int main() 120 { 121 n=read(); 122 rep(i,1,n+1) a[i]=read(); 123 rep(i,1,n){ 124 int from=read(),to=read(); 125 e[from].push_back(to); 126 e[to].push_back(from); 127 } 128 init(); 129 add(a[1],a[1],1); 130 rep(i,1,n){ 131 add(a[i],a[i+1],1); 132 add(a[i],a[i],-1); 133 } 134 add(a[n],a[n],-1); 135 rep(i,1,n+1){ 136 printf("%d\n",sum(1,id[i])); 137 } 138 return 0; 139 }
3631: [JLOI2014]松鼠的新家
Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 856 Solved: 413
[Submit][Status][Discuss]
Description
松鼠的新家是一棵树,前几天刚刚装修了新家,新家有n个房间,并且有n-1根树枝连接,每个房间都可以相互到达,且俩个房间之间的路线都是唯一的。天哪,他居然真的住在“树”上。松鼠想邀请****前来参观,并且还指定一份参观指南,他希望**能够按照他的指南顺序,先去a1,再去a2,……,最后到an,去参观新家。
可是这样会导致**重复走很多房间,懒惰的**不听地推辞。可是松鼠告诉他,每走到一个房间,他就可以从房间拿一块糖果吃。**是个馋家伙,立马就答应了。
现在松鼠希望知道为了保证**有糖果吃,他需要在每一个房间各放至少多少个糖果。因为松鼠参观指南上的最后一个房间an是餐厅,餐厅里他准备了丰盛的大餐,所以当**在参观的最后到达餐厅时就不需要再拿糖果吃了。
Input
第一行一个整数n,表示房间个数
第二行n个整数,依次描述a1-an
接下来n-1行,每行两个整数x,y,表示标号x和y的两个房间之间有树枝相连。
Output
一共n行,第i行输出标号为i的房间至少需要放多少个糖果,才能让**有糖果吃。
Sample Input
5
1 4 5 3 2
1 2
2 4
2 3
4 5
1 4 5 3 2
1 2
2 4
2 3
4 5
Sample Output
1
2
1
2
1
2
1
2
1
HINT
2<= n <=300000