萌新初学点分治,已经调得自闭了……

P3806 【模板】点分治 1

wubaiting2020 @ 2019-10-05 17:31:50

#include<algorithm>
#include<iostream>
#include<iomanip>
#include<cstring>
#include<cstdio>
#include<cmath>
#define LL long long
using namespace std;
const int INF=0x3f3f3f3f,MAXX=100005;
int read()
{
   int s=0,bj=0;
   char ch=getchar();
   while(ch<'0'||ch>'9')bj|=(ch=='-'),ch=getchar();
   while(ch>='0'&&ch<='9')s=(s<<1)+(s<<3)+(ch^48),ch=getchar();
   return bj?-s:s;
}
void printnum(int x)
{
    if(x>9)printnum(x/10);
    putchar(x%10^48);
}
void print(int x,char ch)
{
    if(x<0){putchar('-');x=-x;}
    printnum(x);putchar(ch);
}
struct node{int nx,to,v;}w[200005];int cnt,h[100005];
void AddEdge(int x,int y,int z){w[++cnt].to=y;w[cnt].nx=h[x];w[cnt].v=z;h[x]=cnt;}
int size[100005],son[100005],vst[100005],sum,maxx,tot,root,dis[100005],ans[2000005];//son[]子树中的最大节点数 
int n,m;
void GR(int x,int fa)
{
    size[x]=1;son[x]=0;
    for(int i=h[x];i;i=w[i].nx)
    {
        int y=w[i].to;
        if(y^fa&&!vst[y])
        {
            GR(y,x);//向下递归求解 
            size[x]+=size[y];
            son[x]=max(son[x],size[y]);//更新 
        }
        son[x]=max(son[x],sum-size[x]);//除了这一半子树的另一半子树 
        if(son[x]<maxx)root=x,maxx=son[x]; 
    }
}
void Dis(int x,int fa,int no)
{
    dis[++tot]=no;
    for(int i=h[x];i;i=w[i].nx)
    {
        int y=w[i].to;
        if(y^fa&&!vst[y])Dis(y,x,no+w[i].v);
    }
}
void cal(int x,int bj,int len)
{
    tot=0;Dis(x,-1,len);
    for(int i=1;i<tot;i++)
    for(int j=i+1;j<=tot;j++)
    if(bj)ans[dis[i]+dis[j]]++;
    else ans[dis[i]+dis[j]]--;
}
void solve(int x)
{
    cal(x,1,0);vst[x]=1;//就算答案,标记已访问 
    for(int i=h[x];i;i=w[i].nx)
    {
        int y=w[i].to;
        if(!vst[y])
        {
            cal(y,0,w[i].v);//容斥减去重复状态 
            maxx=INF;sum=size[y];root=0;GR(y,-1);//算出在子树y中的重心 
            solve(root);
        }
    }
}
int main()
{
    int x,y,z;
    n=read();m=read();
    for(int i=1;i<n;i++)
    {
        x=read();y=read();z=read();
        AddEdge(x,y,z);AddEdge(y,x,z);
    }
    sum=n;maxx=INF;GR(1,-1);solve(root);
    for(int i=1;i<=m;i++)
    {
        x=read();
        if(ans[x]>0)puts("AYE");
        else puts("NAY");
    }
    return 0;
}

by Soledad_S @ 2019-10-06 13:08:23

#include<algorithm>
#include<iostream>
#include<iomanip>
#include<cstring>
#include<cstdio>
#include<cmath>
#define LL long long
using namespace std;
const int INF=0x3f3f3f3f,MAXX=100005;
int read()
{
   int s=0,bj=0;
   char ch=getchar();
   while(ch<'0'||ch>'9')bj|=(ch=='-'),ch=getchar();
   while(ch>='0'&&ch<='9')s=(s<<1)+(s<<3)+(ch^48),ch=getchar();
   return bj?-s:s;
}
void printnum(int x)
{
    if(x>9)printnum(x/10);
    putchar(x%10^48);
}
void print(int x,char ch)
{
    if(x<0){putchar('-');x=-x;}
    printnum(x);putchar(ch);
}
struct node{int nx,to,v;}w[200005];int cnt,h[100005];
void AddEdge(int x,int y,int z){w[++cnt].to=y;w[cnt].nx=h[x];w[cnt].v=z;h[x]=cnt;}
int size[100005],son[100005],vst[100005],sum,maxx,tot,root,dis[100005],ans[2000005];//son[]子树中的最大节点数 
int n,m;
void GR(int x,int fa)
{
    size[x]=1;son[x]=0;
    for(int i=h[x];i;i=w[i].nx)
    {
        int y=w[i].to;
        if(y^fa&&!vst[y])
        {
            GR(y,x);//向下递归求解 
            size[x]+=size[y];
            son[x]=max(son[x],size[y]);//更新 
        }
    }
    son[x]=max(son[x],sum-size[x]);//除了这一半子树的另一半子树 
    if(son[x]<maxx)root=x,maxx=son[x]; 

}
void Dis(int x,int fa,int no)
{
    dis[++tot]=no;
    for(int i=h[x];i;i=w[i].nx)
    {
        int y=w[i].to;
        if(y^fa&&!vst[y])Dis(y,x,no+w[i].v);
    }
}
void cal(int x,int bj,int len)
{
    tot=0;Dis(x,-1,len);
    for(int i=1;i<tot;i++)
    for(int j=i+1;j<=tot;j++)
    if(bj)ans[dis[i]+dis[j]]++;
    else ans[dis[i]+dis[j]]--;
}
void solve(int x)
{
    cal(x,1,0);vst[x]=1;//就算答案,标记已访问 
    for(int i=h[x];i;i=w[i].nx)
    {
        int y=w[i].to;
        if(!vst[y])
        {
            cal(y,0,w[i].v);//容斥减去重复状态 
            maxx=INF;sum=size[y];root=0;GR(y,-1);//算出在子树y中的重心 
            solve(root);
        }
    }
}
int main()
{
    int x,y,z;
    n=read();m=read();
    for(int i=1;i<n;i++)
    {
        x=read();y=read();z=read();
        AddEdge(x,y,z);AddEdge(y,x,z);
    }
    sum=n;maxx=INF;GR(1,-1);solve(root);
    for(int i=1;i<=m;i++)
    {
        x=read();
        if(ans[x]>0)puts("AYE");
        else puts("NAY");
    }
    return 0;
}

by Soledad_S @ 2019-10-06 13:08:54

@wubaiting2020 已A,自己找哪个脑残地方写错了


by wubaiting2020 @ 2019-10-06 13:56:52

艹 @Soledad 感谢奆奆……


上一页 |