Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include "bits/stdc++.h"
- #include <x86intrin.h>
- #include<ext/pb_ds/assoc_container.hpp>
- #define MAXN 100009
- #define INF 1000000007
- #define mp(x,y) make_pair(x,y)
- #define all(v) v.begin(),v.end()
- #define pb(x) push_back(x)
- #define wr cout<<"----------------"<<endl;
- #define ppb() pop_back()
- #define tr(ii,c) for(__typeof((c).begin()) ii=(c).begin();ii!=(c).end();ii++)
- #define ff first
- #define ss second
- #define my_little_dodge 46
- #define debug(x) cerr<< #x <<" = "<< x<<endl;
- using namespace __gnu_pbds;
- using namespace std;
- typedef long long ll;
- typedef pair<int,int> PII;
- template<class T>bool umin(T& a,T b){if(a>b){a=b;return 1;}return 0;}
- template<class T>bool umax(T& a,T b){if(a<b){a=b;return 1;}return 0;}
- typedef tree<pair<ll,int>, null_type, less<pair<ll,int> >, rb_tree_tag, tree_order_statistics_node_update> tes;
- const int offset=100001;
- vector<int>adj[MAXN];
- int med[MAXN],men[MAXN],sub[MAXN],vis[MAXN];
- int sz[MAXN*2],multi;
- tes s[MAXN*2];
- ll ans=0;
- void pre(int nd,int pr){
- sub[nd]=1;
- tr(it,adj[nd])
- if(*it!=pr and !vis[*it]){
- pre(*it,nd);
- sub[nd]+=sub[*it];
- }
- }
- int dfs1(int nd,int pr,int sz){
- tr(it,adj[nd])
- if(*it!=pr and !vis[*it] and sub[*it]>sz)
- return dfs1(*it,nd,sz);
- return nd;
- }
- int tap(int x,ll y){
- int res=0;
- for(;x<=200001;x+=x&(-x)){
- if(!sz[x])
- continue;
- int val=sz[x]-s[x].order_of_key(mp(y,0));
- res+=val;
- }
- return res;
- }
- void get(int nd,int pr,int X,ll Y){
- X+=med[nd];Y+=men[nd];
- ans+=(X>=0 and Y>=0);
- ans+=tap(-X+offset,-Y);
- tr(it,adj[nd])
- if(*it!=pr and !vis[*it])
- get(*it,nd,X,Y);
- }
- stack<pair<int,pair<ll,int> > >st;
- void update(int x,ll y,int turn,int id){
- for(;x;x-=x&(-x)){
- if(turn)
- s[x].insert(mp(y,id)),sz[x]++;
- else
- s[x].erase(mp(y,id)),sz[x]--;
- }
- }
- void upd(int nd,int pr,int X,ll Y){
- X+=med[nd];Y+=men[nd];
- ++multi;
- update(X+offset,Y,1,multi);
- st.push(mp(X+offset,mp(Y,multi)));
- tr(it,adj[nd])
- if(*it!=pr and !vis[*it])
- upd(*it,nd,X,Y);
- }
- void solve(int nd){
- ans+=(med[nd]>=0 and men[nd]>=0);
- for(int i=0;i<int(adj[nd].size());i++){
- int to=adj[nd][i];
- if(vis[to])
- continue;
- get(to,-1,med[nd],men[nd]);
- upd(to,-1,0,0);
- }
- while(!st.empty()){
- int xx=st.top().ff;
- ll yy=st.top().ss.ff;
- int mm=st.top().ss.ss;
- st.pop();
- update(xx,yy,0,mm);
- }multi=0;
- }
- void dfs(int nd){
- pre(nd,-1);
- int centr=dfs1(nd,-1,sub[nd]>>1);
- vis[centr]=1;solve(centr);
- tr(it,adj[centr])
- if(!vis[*it])
- dfs(*it);
- }
- int main(){
- srand(__rdtsc());
- //~ freopen("file.in", "r", stdin);
- int t=2;
- //~ scanf("%d",&t);
- while(t--){
- int n=100000,X=rand()%1000000000,Y=rand()%1000000000;
- //~ scanf("%d%d%d",&n,&X,&Y);
- for(int i=1;i<=n;i++){
- int x=rand()%1000000000;
- //~ scanf("%d",&x);
- med[i]=(x<=X)*2-1;
- men[i]=x-Y;
- }
- for(int i=2;i<=n;i++){
- int u=rand()%(i-1)+1,v=i;
- //~ scanf("%d%d",&u,&v);
- adj[u].pb(v);
- adj[v].pb(u);
- }dfs(1);
- printf("%lld\n",ans);
- for(int i=1;i<=n;i++)
- vis[i]=0,adj[i].clear();
- ans=0;
- }
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement