HDU - 5877 Weak Pair 2016 ACM/ICPC 大连网络赛 J题 dfs+树状数组+离散化
題目鏈接
You are given a?rootedrooted?tree of?NN?nodes, labeled from 1 to?NN. To the?iith node a non-negative value?aiai?is assigned.An?orderedordered?pair of nodes?(u,v)(u,v)?is said to be?weakweakif?
??(1)?uu?is an ancestor of?vv?(Note: In this problem a node?uu?is not considered an ancestor of itself);?
??(2)?au×av≤kau×av≤k.?
Can you find the number of weak pairs in the tree?
Input
There are multiple cases in the data set.?
??The first line of input contains an integer?TT?denoting number of test cases.?
??For each case, the first line contains two space-separated integers,?NN?and?kk, respectively.?
??The second line contains?NN?space-separated integers, denoting?a1a1?to?aNaN.?
??Each of the subsequent lines contains two space-separated integers defining an edge connecting nodes?uu?and?vv?, where node?uu?is the parent of node?vv.?
??Constrains:?
???
??1≤N≤1051≤N≤105?
???
??0≤ai≤1090≤ai≤109?
???
??0≤k≤10180≤k≤1018
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
題意:給你一棵樹以及單項邊,以及每個點的權值,如果每一個點與其祖先的權值乘積<=k,ans+1
拿到這個題目,第一個想法就是在dfs的過程中將維護祖先的權值,就是dfs某個點時將權值加入set,dfs完了就刪除,然后查詢
s.upper_bround找到大于該點權值的下標,但是發現無法將set里邊的下標取出,因為set是無序的
然后第二就是異想天開的用vector維護一個升序的,用上述相同方法,但是TLE,發現了vector的插入刪除是O(n)的
我的stl問題太大了。
正確思路,將所有的權值以及k/val離散,因為是維護的大小,所以用樹狀數組來維護即可。
#include<stdio.h>
#include<string.h>
#include<iostream>
#include<algorithm>
#include<math.h>
#include<set>
#include<stack>
#include<vector>
#include<map>
#include<queue>
#define myself i,l,r
#define lson i<<1
#define rson i<<1|1
#define Lson i<<1,l,mid
#define Rson i<<1|1,mid+1,r
#define half (l+r)/2
#define inff 0x3f3f3f3f
#define lowbit(x) x&(-x)
#define PI 3.14159265358979323846
#define min4(a,b,c,d) min(min(a,b),min(c,d))
#define min3(x,y,z) min(min(x,y),min(y,z))
#define pii make_pair
#define pr pair<int,int>
const int dir[6][2]= {2,0,-2,0,-1,3,-1,-3,1,-3,1,3};
typedef long long ll;
const ll inFF=9223372036854775807;
typedef unsigned long long ull;
using namespace std;
const int maxn=2e5+5;
int head[maxn],sign,ans;
int in[maxn];
struct node
{int to,p;
}edge[maxn<<1];
struct nod
{ll x;int i,val;
}a[maxn];
bool cmp1(nod s,nod e){return s.x<e.x;}
bool cmp2(nod s,nod e){return s.i<e.i;}
int c[maxn];
int m,n;
ll k;
void edge_add(int u,int v)
{edge[sign]=node{v,head[u]};head[u]=sign++;
}
void add(int x,int val)
{while(x<=n){c[x]+=val;x+=lowbit(x);}
}
int query(int x) //求前n項的和.
{int sum=0;while(x>0){sum+=c[x];x-=lowbit(x);}return sum;
}
void init()
{sign=ans=a[0].x=0;for(int i=0;i<=n;i++){head[i]=-1;c[i]=in[i]=0;}
}
void dfs(int u)
{ans+=query(a[u+m].val);add(a[u].val,1);for(int i=head[u];~i;i=edge[i].p){int v=edge[i].to;dfs(v);}add(a[u].val,-1);
}
int main()
{int t,x,y,root;cin>>t;while(t--){scanf("%d %lld",&m,&k);n=2*m,init();for(int i=1;i<=m;i++){scanf("%lld",&a[i].x),a[i].i=i;a[i+m].x=a[i].x?(k/a[i].x):inFF;a[i+m].i=i+m;}sort(a+1,a+1+n,cmp1);for(int i=1;i<=n;i++){if(a[i].x!=a[i-1].x) a[i].val=a[i-1].val+1;else a[i].val=a[i-1].val;}sort(a+1,a+1+n,cmp2);for(int i=1;i<m;i++) scanf("%d %d",&x,&y),edge_add(x,y),in[y]++;for(int i=1;i<=m;i++) if(in[i]==0) {root=i;break;}dfs(root);printf("%d\n",ans);}return 0;
}
?
總結
以上是生活随笔為你收集整理的HDU - 5877 Weak Pair 2016 ACM/ICPC 大连网络赛 J题 dfs+树状数组+离散化的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: POJ 2226 Muddy Field
- 下一篇: HDU - 5876 Sparse Gr