当前位置: 代码迷 >> 综合 >> HDU 5877 Weak Pair (树状数组+DFS)
  详细解决方案

HDU 5877 Weak Pair (树状数组+DFS)

热度:54   发布时间:2023-11-15 12:59:58.0

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5877

#include<bits/stdc++.h>
using namespace std;#define debug puts("YES");
#define rep(x,y,z) for(int (x)=(y);(x)<(z);(x)++)
#define ll long long#define lrt int l,int r,int rt
#define lson l,mid,rt<<1
#define rson mid+1,r,rt<<1|1
#define root l,r,rt
#define mst(a,b) memset((a),(b),sizeof(a))
#define pii pair<ll,ll>
#define mk(x,y) make_pair(x,y)
const int mod=1e9+7;
const int maxn=2e5+9;
const int ub=1e6;
ll powmod(ll x,ll y){ll t; for(t=1;y;y>>=1,x=x*x%mod) if(y&1) t=t*x%mod; return t;}
ll gcd(ll x,ll y){return y?gcd(y,x%y):x;}
ll a[maxn],b[maxn],k,n,ans;
/*
题目大意:给定一颗树,问满足条件的二元组数量是多少
(i,j)其中ai*aj<=k,a序列和k事先给定。题目分析:看到不等关系想到树状数组,但是这题结构不同于序列,
是树的结构,但是树中描述序列关系可以用DFS序,把树的深搜产生的序列,
用括号匹配的思想描述出来,对于当前节点i,我们考虑其对答案的影响是
在回溯回该节点之前都存在的,当回溯完毕后消去影响,这样关系就描述出来了,
然后就是这题的数据范围需要离散化再用树状数组处理,注意ai值为0的情况,
其对应的离散化值应该是maxn-1这样的状态,表示无限大。时间复杂度:O(nlogn)。
*/
///前式链向星
struct node{int u,nxt;}e[maxn];
int head[maxn],x,y,tot;
void init(){mst(head,-1),tot=0;}
void add(int x,int y){e[tot]=node{y,head[x]};head[x]=tot++;
}
ll tmp[maxn],idx;///
///BIT
int lowbit(int x){return x&-x;}
int tree[maxn];
void refresh(int x,int d){for(;x<maxn;tree[x]+=d,x+=lowbit(x));
}
int sum(int x){int ret=0;for(;x>0;ret+=tree[x],x-=lowbit(x));return ret;
}
void dfs(int u,int pre){ans+=1LL*sum(b[u]);refresh(a[u],1);///for(int i=head[u];~i;i=e[i].nxt){int y=e[i].u;if(y==pre) continue;dfs(y,u);}refresh(a[u],-1);
}int vis[maxn],rt;
int main(){int t;scanf("%d",&t);while(t--){mst(tree,0),mst(vis,0);idx=ans=0,init();///初始化scanf("%lld%lld",&n,&k);rep(i,1,n+1){scanf("%lld",&a[i]);if(a[i]) b[i]=k/a[i];else b[i]=1LL*maxn-1;tmp[idx++]=b[i];tmp[idx++]=a[i];}sort(tmp,tmp+idx);idx=unique(tmp,tmp+idx)-tmp;///离散化rep(i,1,n+1){a[i]=lower_bound(tmp,tmp+idx,a[i])-tmp+1;b[i]=lower_bound(tmp,tmp+idx,b[i])-tmp+1;}rep(i,1,n){scanf("%d%d",&x,&y);add(x,y),add(y,x);///vis[y]=1;}rep(i,1,n+1) if(!vis[i]) {rt=i;break;}ans=0;dfs(rt,-1);///printf("%lld\n",ans);}return 0;
}