Weak PairTime Limit: 4000/2000 MS (Java/Others) Memory Limit: 262144/262144 K (Java/Others)Total Submission(s): 6001 Accepted Submission(s): 1690 Problem Description You are given a rooted tree of N nodes, labeled from 1 to N . To the i th node a non-negative value ai is assigned.An ordered pair of nodes (u,v) is said to be weak if
Input There are multiple cases in the data set.
Output For each test case, print a single integer on a single line denoting the number of weak pairs in the tree.
Sample Input 1 2 3 1 2 1 2
Sample Output 1
Source 2016 ACM/ICPC Asia Regional Dalian Online
Recommend wange2014 |
首先离散化,然后把每一个ai和k/ai都离散化,加入数组,然后排序。接着深搜,对于每一个点,到达它时它的祖先一定到达过,所以利用树状数组,统计在它之前比k/ai小于或等于的数,然后更新。
参考:https://blog.csdn.net/queuelovestack/article/details/52505856
#include <algorithm> //STL通用算法
#include <bitset> //STL位集容器
#include <cctype>
#include <cerrno>
#include <clocale>
#include <cmath>
#include <complex> //复数类
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <ctime>
#include <deque> //STL双端队列容器
#include <exception> //异常处理类
#include <fstream>
#include <functional> //STL定义运算函数(代替运算符)
#include <limits>
#include <list> //STL线性列表容器
#include <map> //STL 映射容器
#include <iomanip>
#include <ios> //基本输入/输出支持
#include<iosfwd> //输入/输出系统使用的前置声明
#include <iostream>
#include <istream> //基本输入流
#include <ostream> //基本输出流
#include <queue> //STL队列容器
#include <set> //STL 集合容器
#include <sstream> //基于字符串的流
#include <stack> //STL堆栈容器
#include <stdexcept> //标准异常类
#include <streambuf> //底层输入/输出支持
#include <string> //字符串类
#include <utility> //STL通用模板类
#include <vector> //STL动态数组容器
#include <cwchar>
#include <cwctype>
#define ll long long
using namespace std;
priority_queue<int,vector<int>,less<int> >q;
int dx[]= {-1,1,0,0,-1,-1,1,1};
int dy[]= {0,0,-1,1,-1,1,1,-1};
const int maxn = 100000+66;
const ll mod=10007;
const ll INF =1e18+2;
ll n,k;
ll a[maxn];
ll b[maxn*2];
struct Edge
{
ll from;
ll to;
ll next;
} e[maxn];
int tot;
int head[maxn];
void Add_Edge(int u,int v,int *head)
{
e[++tot].to=v;
e[tot].from=u;
e[tot].next=head[u];
head[u]=tot;
}
ll ans;
int len;
ll c[maxn*2];
int lowbit(int x)
{
return x&(-x);
}
ll Sum(int x)
{
ll sum=0;
while(x>0)
{
sum+=c[x];
x-=lowbit(x);
}
return sum;
}
void Update(int x,ll v)
{
while(x<=len)
{
c[x]=c[x]+v;
x+=lowbit(x);
}
}
void dfs(ll x)
{
ans+=Sum(lower_bound(b,b+len,a[x]?k/a[x]:INF)-b+1);
//cout<<Sum(lower_bound(b,b+len,a[x]?k/a[x]:INF)-b+1)<<"---"<<endl;
Update(lower_bound(b,b+len,a[x])-b+1,1);
for(int i=head[x];i;i=e[i].next)
{
ll v=e[i].to;
dfs(v);
}
Update(lower_bound(b,b+len,a[x])-b+1,-1);
}
bool vis[maxn];
void init()
{
tot=0;
ans=0;
len=0;
memset(head,0,sizeof(head));
memset(c,0,sizeof(c));
memset(vis,false,sizeof(vis));
memset(e,0,sizeof(e));
memset(b,0,sizeof(b));
}
int main()
{
int t;
while(scanf("%d",&t)!=EOF)
{
while(t--)
{
init();
scanf("%lld %lld",&n,&k);
for(int i=1; i<=n; i++)
{
scanf("%lld",&a[i]);
b[len++]=a[i];
if(a[i]!=0)
{
b[len++]=k/a[i];
}
else
{
b[len++]=INF;
}
}
sort(b,b+len);
len=unique(b,b+len)-b;
for(int i=1; i<n; i++)
{
ll u,v;
scanf("%lld %lld",&u,&v);
vis[v]=true;
Add_Edge(u,v,head);
}
for(int i=1; i<=n; i++)
{
if(!vis[i])
{
dfs(i);
}
}
printf("%I64d\n",ans);
}
}
}