HDU6430 Problem E. TeaTree

每个点开个set记录一蛤当前连通块中有哪些因数了,树上dfs下去启发式合并一蛤,一个点的答案必定是两个不同子树中的共同因数,取个大的就行了,3900+ms飘过了233,今天才知道set的clear是可以清空内存的,一开始MLE了,然后vector 清空内存直接swap(e[i],vector())就能内存回收。这题好像有另一种形式,一个序列和另外一个序列任选两个数,然后求最大gcd是多少,也是对每一个数字存所有因数,复杂度nlogn就行了。

#include
#define maxl 100010

using namespace std;

int n,cnt;
int fa[maxl],ehead[maxl],val[maxl];
struct ed
{
    int to,nxt;
}e[maxl<<1];
vector  num[maxl];
set  s1[maxl],s2;
set  :: iterator it;
int ans[maxl];

inline void add(int u,int v)
{
    e[++cnt].to=v;e[cnt].nxt=ehead[u];ehead[u]=cnt;
}

inline void prework()
{
    for(int i=1;i<=n;i++)
        ehead[i]=0,ans[i]=-1,s1[i].clear();
    cnt=0;
    for(int i=2;i<=n;i++)
    {
        scanf("%d",&fa[i]);
        add(fa[i],i);
    }
    for(int i=1;i<=n;i++)
        scanf("%d",&val[i]);
}

inline int max(int a,int b)
{
    if(a>b)return a;
    else return b;
}

inline void dfs(int u)
{
    int v,szu,szv,l=num[val[u]].size(),d;
    for(int i=0;iS;
        s1[v].swap(S);
        //s1[v].clear();
    }
}

inline void mainwork()
{
    dfs(1);
}

inline void print()
{
    for(int i=1;i<=n;i++)
        printf("%d\n",ans[i]);
}

int main()
{
    for(int i=1;i

 

你可能感兴趣的:(启发式合并)