能力不足,待填坑
P3676 小清新数据结构题
P2664 树上游戏
用于求树上的满足条件的点对个数
例如最基本的求树上所有满足x到y的距离为k,是k的倍数等等的点对个数
模板
#include<iostream>//注意此模板点的下标应为1到n!!!
#include<cstdio>
#include<vector>
using namespace std;
const int MAX_N=20100;
const int INF=0x3f3f3f3f;
int son[MAX_N],max_son[MAX_N],dis[MAX_N];
bool vis[MAX_N];
long long ans=0;
int root;
int cnt,sum;
vector<int>v[MAX_N],w[MAX_N];
void dfs(int now,int fa){
int i;
son[now]=1;
max_son[now]=0;
for(i=0;i<v[now].size();i++){
int to=v[now][i];
if(to==fa||vis[to])
continue;
dfs(to,now);
son[now]+=son[to];
max_son[now]=max(max_son[now],son[to]);
}
max_son[now]=max(max_son[now],sum-son[now]);
if(max_son[now]<max_son[root])
root=now;
}
void getdis(int now,int fa,int d){
int i;
dis[++cnt]=d;
for(i=0;i<v[now].size();i++){
int to=v[now][i];
if(to==fa||vis[to])
continue;
getdis(to,now,d+w[now][i]);
}
}
int Calc(int now,int d){
int i,j;
int res=0;
cnt=0;
getdis(now,0,d);
//从now点出发的所有点都储存在dis数组中,为[1,cnt]。
//每个点最多被分治log次,复杂度为logn*T,T为Calc的复杂度。
}
void divide(int now){
int i;
ans+=Calc(now,0);
vis[now]=true;
for(i=0;i<v[now].size();i++){
int to=v[now][i];
if(vis[to])
continue;
ans-=Calc(to,w[now][i]);
sum=son[to];
root=0;
dfs(to,0);
divide(root);
}
}
int main(void){
int n,i,a,b,c;
scanf("%d",&n);
for(i=1;i<n;i++){
scanf("%d%d%d",&a,&b,&c);
v[a].push_back(b);
w[a].push_back(c);
v[b].push_back(a);
w[b].push_back(c);
}
sum=n;
max_son[0]=n;
root=0;
dfs(1,0);
divide(root);
//ans
return 0;
}
#include<iostream>
#include<cstdio>
#include<vector>
using namespace std;
const int MAX_N=20100;
const int INF=0x3f3f3f3f;
int son[MAX_N],max_son[MAX_N],dis[MAX_N];
bool vis[MAX_N];
long long ans=0;
int root;
int cnt,sum;
vector<int>v[MAX_N],w[MAX_N];
void dfs(int now,int fa){
int i;
son[now]=1;
max_son[now]=0;
for(i=0;i<v[now].size();i++){
int to=v[now][i];
if(to==fa||vis[to])
continue;
dfs(to,now);
son[now]+=son[to];
max_son[now]=max(max_son[now],son[to]);
}
max_son[now]=max(max_son[now],sum-son[now]);
if(max_son[now]<max_son[root])
root=now;
}
void getdis(int now,int fa,int d){
int i;
dis[++cnt]=d;
for(i=0;i<v[now].size();i++){
int to=v[now][i];
if(to==fa||vis[to])
continue;
getdis(to,now,d+w[now][i]);
}
}
void solve(int now,int d,int k){
int i,j;
cnt=0;
getdis(now,0,d);
long long a[3]={0};
for(i=1;i<=cnt;i++){
a[dis[i]%3]+=1;
}
ans+=k*(a[0]*a[0]+a[1]*a[2]+a[2]*a[1]);
}
void divide(int now){
int i;
solve(now,0,1);
vis[now]=true;
for(i=0;i<v[now].size();i++){
int to=v[now][i];
if(vis[to])
continue;
solve(to,w[now][i],-1);
sum=son[to];
root=0;
dfs(to,0);
divide(root);
}
}
long long gcd(long long a,long long b){
return b?gcd(b,a%b):a;
}
int main(void){
int n,i,a,b,c;
scanf("%d",&n);
for(i=1;i<n;i++){
scanf("%d%d%d",&a,&b,&c);
v[a].push_back(b);
w[a].push_back(c);
v[b].push_back(a);
w[b].push_back(c);
}
sum=n;
max_son[0]=n;
root=0;
dfs(1,0);
divide(root);
long long x=n*n;
//cout<<ans<<" "<<x<<"\n";
long long g=gcd(x,ans);
printf("%lld/%lld\n",ans/g,x/g);
return 0;
}
#include<iostream>
#include<cstdio>
#include<vector>
using namespace std;
const int MAX_N=20100;
const int INF=0x3f3f3f3f;
int have[10010000];
int son[MAX_N],max_son[MAX_N],dis[MAX_N];
bool vis[MAX_N];
long long ans=0;
int root;
int cnt,sum;
vector<int>v[MAX_N],w[MAX_N];
void dfs(int now,int fa){
int i;
son[now]=1;
max_son[now]=0;
for(i=0;i<v[now].size();i++){
int to=v[now][i];
if(to==fa||vis[to])
continue;
dfs(to,now);
son[now]+=son[to];
max_son[now]=max(max_son[now],son[to]);
}
max_son[now]=max(max_son[now],sum-son[now]);
if(max_son[now]<max_son[root])
root=now;
}
void getdis(int now,int fa,int d){
int i;
dis[++cnt]=d;
for(i=0;i<v[now].size();i++){
int to=v[now][i];
if(to==fa||vis[to])
continue;
getdis(to,now,d+w[now][i]);
}
}
void solve(int now,int d,int k){
int i,j;
cnt=0;
getdis(now,0,d);
for(i=1;i<=cnt;i++){
for(j=1;j<=cnt;j++){
have[dis[i]+dis[j]]+=k;
}
}
}
void divide(int now){
int i;
solve(now,0,1);
vis[now]=true;
for(i=0;i<v[now].size();i++){
int to=v[now][i];
if(vis[to])
continue;
solve(to,w[now][i],-1);
sum=son[to];
root=0;
dfs(to,0);
divide(root);
}
}
int main(void){
int n,i,a,b,c,m,k;
scanf("%d%d",&n,&m);
for(i=1;i<n;i++){
scanf("%d%d%d",&a,&b,&c);
v[a].push_back(b);
w[a].push_back(c);
v[b].push_back(a);
w[b].push_back(c);
}
sum=n;
max_son[0]=n;
root=0;
dfs(1,0);
divide(root);
for(i=0;i<m;i++){
scanf("%d",&k);
if(have[k]!=0)
cout<<"AYE\n";
else
cout<<"NAY\n";
}
return 0;
}