NC252105. The Number Of Black Edges
描述
输入描述
The first line contains two integers and , separated by a space. Here, represents the number of nodes on the tree, and represents the total number of operations.
Next, there are lines, where the -th line contains two integers and , representing the two nodes connected by the -th edge on the tree. Following these are lines, each representing one operation. The format of each operation is as follows:
- 1 x: Assign the color black to the edge indexed by .
- 2 x: Assign the color white to the edge indexed by .
- 3 x: Count the sum of the number of black edges on the simple path from all odd-indexed nodes to the node indexed by .
输出描述
For each operation 3, output a single integer in a line, indicating the sum of the number of black edges on the simple path from all odd-indexed nodes to the node indexed by , where is the parameter of the operation.
示例1
输入:
5 5 1 2 1 3 1 4 1 5 1 1 3 2 3 3 2 1 3 2
输出:
3 0 0
示例2
输入:
11 10 11 2 10 2 1 5 1 4 2 6 4 9 8 5 5 7 2 3 2 1 2 9 2 1 1 1 3 3 1 1 1 8 1 5 2 10 1 8 3 8
输出:
1 2
C++(g++ 7.5.0) 解法, 执行用时: 82ms, 内存消耗: 12072K, 提交时间: 2023-05-25 12:00:52
#include<bits/stdc++.h> #define pb push_back using namespace std; using ll=long long; using pii=pair<int,int>; const int N=1e5+5; vector<int>G[N]; int n,m; int f[N],l[N],r[N]; int son[N],col[N]; pii e[N]; int tot; void dfs(int u,int p) { f[u]=p; l[u]=++tot; if(u&1)son[u]++; for(auto v:G[u]){ if(v!=p){ dfs(v,u); son[u]+=son[v]; } } r[u]=tot; } ll a[N],tr[N<<2],tag[N<<2]; #define ls ((p)*2) #define rs ((p)*2+1) #define mid (((pl)+(pr))/2) void pushup(int p) { tr[p]=tr[ls]+tr[rs]; } void addtag(int p,int pl,int pr,ll d) { tag[p]+=d; tr[p]+=d*(pr-pl+1); } void pushdown(int p,int pl,int pr) { if(tag[p]){ addtag(ls,pl,mid,tag[p]); addtag(rs,mid+1,pr,tag[p]); tag[p]=0; } } void change(int l,int r,ll d,int p=1,int pl=1,int pr=n) { if(l<=pl&&pr<=r){ addtag(p,pl,pr,d); return; } pushdown(p,pl,pr); if(l<=mid)change(l,r,d,ls,pl,mid); if(r>mid)change(l,r,d,rs,mid+1,pr); pushup(p); } ll query(int l,int r,int p=1,int pl=1,int pr=n) { if(l<=pl&&pr<=r)return tr[p]; pushdown(p,pl,pr); ll res=0; if(l<=mid)res+=query(l,r,ls,pl,mid); if(mid<r)res+=query(l,r,rs,mid+1,pr); return res; } ll ans; void update(int x,ll flag) { if(col[x]==flag)return; col[x]=flag; flag=flag*2-1; auto [u,v]=e[x]; if(f[u]==v)swap(u,v); ans+=flag*son[v]; change(l[v],r[v],flag*(son[1]-son[v]*2)); } int main() { scanf("%d%d",&n,&m); for(int i=1,u,v;i<n;i++){ scanf("%d%d",&u,&v); G[u].pb(v); G[v].pb(u); e[i]={u,v}; } dfs(1,1); while(m--){ int op,x; scanf("%d%d",&op,&x); if(op<=2){ update(x,2-op); }else{ printf("%lld\n",ans+query(l[x],l[x])); } } }
C++(clang++ 11.0.1) 解法, 执行用时: 54ms, 内存消耗: 8760K, 提交时间: 2023-05-31 18:11:50
#pragma GCC optimize(3,"Ofast","inline") #include<bits/stdc++.h> using namespace std; #define endl '\n' #define inf 0x3f3f3f3f typedef long long ll; typedef pair<ll,ll> PII; typedef __int128 ull; typedef unsigned int ui; const ll mod=1e9+7; const int N=1e5+10; vector<int>g[N]; int n,q; int dep[N],odd[N],dfn[N],dfn_r[N],idx; int col[N]; struct node { int fa,son; }e[N]; ll tr[N]; void add(int k,int x){ for(;k<=n;k+=k&-k)tr[k]+=x; } ll ask(int k){ ll res=0; for(;k;k-=k&-k){ res+=tr[k]; } return res; } void modify(int l,int r,int x){ add(l,x),add(r+1,-x); } void dfs(int u,int fa){ dfn[u]=++idx; dep[u]=dep[fa]+1; odd[u]=u&1; for(auto j:g[u]){ if(j^fa){ dfs(j,u); odd[u]+=odd[j]; } } dfn_r[u]=idx; } int main(){ ios :: sync_with_stdio (false);cin .tie (0);cout .tie (0); #ifdef newbie freopen("input.in","r",stdin); freopen("output.out","w",stdout); #endif cin>>n>>q; for(int i=1;i<n;i++){ int a,b;cin>>a>>b; e[i]={a,b}; g[a].push_back(b),g[b].push_back(a); } dfs(1,0); for(int i=1;i<n;i++){ if(dep[e[i].fa]>dep[e[i].son])swap(e[i].fa,e[i].son); } while(q--){ int op,x; cin>>op>>x; if(op==3){ cout<<ask(dfn[x])<<endl; } else { int d=op==1?1:-1; int u=e[x].son; if(col[x]==2-op)continue; col[x]=2-op; int l=dfn[u],r=dfn_r[u]; modify(1,l-1,d*odd[u]),modify(r+1,n,d*odd[u]); modify(l,r,d*(odd[1]-odd[u])); } } return 0; }