您的位置:首页 > 大数据 > 人工智能

HDU 5877 Weak Pair

2016-09-10 23:16 274 查看
题目:Weak Pair

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

题意:给一棵树和一个定值k,每个点的值w,对于两点(u、v),如果u 是v 的祖先,且w[u]*w[v]<=k,则说u、v是弱的,问树中有多少对u、v是弱的。

思路:

  第一个要求u 是v 的祖先,那么可以dfs,遍历到v时,所有他上方的都是满足第一条件的u,做多了树就很容易想到在退出某个子树的时候消除这个影响,这样就能保证所有有影响的都是祖先。要求w[u]*w[v]<=k,那么到v的时候,所有小于等于k/w[v]的u都满足,可以想到树状数组。结点的值最大10亿,肯定要离散化,离散化的时候要把k/w[v]加进去一起离散。

AC代码:

#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<math.h>
#include<set>
#include<map>
#include<list>
#include<stack>
#include<queue>
#include<vector>
#include<string>
#include<iostream>
#include<algorithm>
using namespace std;
#define lson rt<<1
#define rson rt<<1|1
#define N 100010
#define M 100010
#define Mod 1000000007
#define LL long long
#define INF 0x7fffffff
#define FOR(i,f_start,f_end) for(int i=f_start;i<=f_end;i++)
#define For(i,f_start,f_end) for(int i=f_start;i<f_end;i++)
#define REP(i,f_end,f_start) for(int i=f_end;i>=f_start;i--)
#define Rep(i,f_end,f_start) for(int i=f_end;i>f_start;i--)
#define MT(x,i) memset(x,i,sizeof(x))
#define gcd(x,y) __gcd(x,y)
const double PI = acos(-1);

int c[N<<1];
int Lowbit(int x)
{
return x&(-x);
}
int getsum(int pos)
{
int sum=0;
while(pos>0)
{
sum+=c[pos];
pos-=Lowbit(pos);
}
return sum;
}
void update(int pos,int num,int n)
{
while(pos<=n)
{
c[pos]+=num;
pos+=Lowbit(pos);
}
}

int n;
LL sum,k;
LL w[N<<1];
vector<int> v
;
int p[N<<1];
int xin;
void dfs(int rt)
{
int pos;
pos=w[rt+n];
sum += getsum(pos);

update(w[rt],1,xin);
For(i,0,v[rt].size()){
int son = v[rt][i];
dfs(son);
}
update(w[rt],-1,xin);
}

bool cmp(int x,int y)
{
return w[x]<w[y];
}

bool f
;
int main()
{
int t,x,y;
scanf("%d",&t);
while(t--)
{
scanf("%d%I64d",&n,&k);
FOR(i,1,n){
scanf("%I64d",&w[i]);
if(w[i]==0) w[n+i]=INF;
else w[n+i]=k/w[i];
p[i]=i;
p[n+i]=n+i;
}
sort(p+1,p+n+n+1,cmp);
xin = 0;
int pre = -1;
FOR(i,1,n+n)
{
if(w[p[i]]>pre){ pre=w[p[i]]; w[p[i]]=++xin; }
else{ pre=w[p[i]]; w[p[i]]=xin; }
}
memset(f,0,sizeof(f));
For(i,1,n){
scanf("%d%d",&x,&y);
v[x].push_back(y);
f[y]=1;
}
MT(c,0);
sum = 0;
FOR(i,1,n){
if(f[i]==false)
{
dfs(i);
break;
}
}
printf("%I64d\n",sum);
FOR(i,1,n){
v[i].clear();
}
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: