HDU - 5877 Weak Pair (dfs序+树状数组+离散化)
生活随笔
收集整理的這篇文章主要介紹了
HDU - 5877 Weak Pair (dfs序+树状数组+离散化)
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
VJ地址
題意:給一個有根樹給你,計算一下滿足下列條件的序列對的數目
(1)u是v的祖先(不能是它自己)
(2)a[v]*a[u]<=k
思路:用DFS序分裂每一條鏈,使鏈上的點都是當前加入點的祖先,用樹狀數組維護,or線段樹,因為是單點修改就用就樹狀數組了。 每次加入點前,計算小于等于k/a[v]點的數量。還有數據大小是1e9,但是只有1e5個點,要離散化處理。
ps:還有要自己找到根節點。
具體細節:
#pragma comment(linker, "/STACK:1024000000,1024000000") #include <bits/stdc++.h> #define INF 2e18 #define inf 0x3f3f3f3f #define FILL(a,b) (memset(a,b,sizeof(a))) #define re register #define lson rt<<1 #define rson rt<<1|1 #define lowbit(a) ((a)&-(a)) #define ios std::ios::sync_with_stdio(false);std::cin.tie(0);std::cout.tie(0); #define fi first #define se secondusing namespace std; typedef long long ll; typedef unsigned long long ull; typedef pair<int,int > pii; int dx[4]= {-1,1,0,0},dy[4]= {0,0,1,-1}; const ll mod=1e9+7; const ll N =2e5+10; const double eps = 1e-4; const double pi=acos(-1); ll gcd(int a,int b){return !b?a:gcd(b,a%b);} using namespace std; vector<int> g[N]; ll n,k; ll a[N]; ll lsh[N]; ll sum; ll cnt; ll c[N]; int vis[N]; ll getid(ll x) {return lower_bound(lsh+1,lsh+cnt+1,x)-lsh; } void add(ll x,ll v) {while(x<=N){c[x]+=v;x+=lowbit(x);} } ll query(ll x) {ll ans=0;while(x){ans+=c[x];x-=lowbit(x);}return ans; } void dfs(int u,int p){add(getid(a[u]),1);for(int v:g[u]){if(v==p) continue;sum+=query(getid(k/a[v]+1)-1);dfs(v,u);}add(getid(a[u]),-1); } void sovle(){sum=0;cin>>n>>k;FILL(c,0);FILL(vis,0);for(int i=1;i<=n;i++) {cin>>a[i];lsh[i]=a[i];}sort(lsh+1,lsh+1+n);cnt=unique(lsh+1,lsh+n+1)-lsh-1;for(int i=1;i<n;i++){int u,v;cin>>u>>v;g[u].push_back(v);g[v].push_back(u);vis[v]=1;}for(int i=1;i<=n;i++){if(!vis[i]) {dfs(i,0);break;}}cout<<sum<<endl;for(int i=1;i<=n;i++) g[i].clear(); } int main() {iosint t=1;cin>>t;while(t--){sovle();}return 0; }總結
以上是生活随笔為你收集整理的HDU - 5877 Weak Pair (dfs序+树状数组+离散化)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 牛客练习赛74 E CCA的期望(算概率
- 下一篇: 新买的手机第一次充电充多久 给新手机充电