4154: [Ipsc2015]Generating Synergy K-D tree

按照dfs序建K-D树,用deepi表示i在原树中的深度,想想成二维平面中的点,第一维是dfs序,第二维是深度,则对于一个染色操作其实就是在二维平面内的区域[inx..outx][deepx..deepx+l]内进行覆盖,可以用K-D树来解决。
sb错误get。。

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#define inf 1e9
#define N 100005
#define ll long long 
#define mod 1000000007
using namespace std;
int n,c,q,a,l,x1,x2,y1,y2,D,dfn,cnt,ans,root;
struct node 
{
    int d[2],mn[2],mx[2];
    int tag,col,fa;
};
node tree[N];
int ls[N],rs[N];
int head[N],deep[N],next[N],list[N],in[N],out[N],id[N],stack[N];
inline int read()
{
    int a=0,f=1; char c=getchar();
    while (c<'0'||c>'9') {if (c=='-') f=-1; c=getchar();}
    while (c>='0'&&c<='9') {a=a*10+c-'0'; c=getchar();}
    return a*f;
}
inline void insert(int x,int y)
{
    next[++cnt]=head[x];
    head[x]=cnt;
    list[cnt]=y;
}
inline bool operator<(node a,node b)
{
    return a.d[D]<b.d[D];
}
void dfs(int x)
{
    in[x]=++dfn; 
    tree[x].d[0]=dfn; tree[x].d[1]=deep[x]; tree[x].tag=x;
    for (int i=head[x];i;i=next[i]) 
    {
        deep[list[i]]=deep[x]+1;
        dfs(list[i]);
    }
    out[x]=dfn;
}
inline void pushup(int k)
{
    id[tree[k].tag]=k; tree[k].tag=0; tree[k].col=1;
    for (int i=0;i<=1;i++)
    {
        tree[k].mn[i]=min(tree[k].d[i],min(tree[ls[k]].mn[i],tree[rs[k]].mn[i]));
        tree[k].mx[i]=max(tree[k].d[i],max(tree[ls[k]].mx[i],tree[rs[k]].mx[i]));
    }
}
void build(int &k,int l,int r,int dir,int f)
{
    int mid=l+r>>1; k=mid; D=dir;   
    nth_element(tree+l,tree+mid,tree+r+1);
    tree[k].fa=f; //要写在上一句下面!
    if (l<mid) build(ls[k],l,mid-1,dir^1,k); else ls[k]=0;
    if (r>mid) build(rs[k],mid+1,r,dir^1,k); else rs[k]=0;
    pushup(k); 
}
inline void pushdown(int k)
{
    if (tree[k].tag)
    {
        if (ls[k]) tree[ls[k]].tag=tree[ls[k]].col=tree[k].tag;
        if (rs[k]) tree[rs[k]].tag=tree[rs[k]].col=tree[k].tag;
        tree[k].tag=0;
    }
}
void change(int k)
{
    if (tree[k].mn[0]>x2||tree[k].mx[0]<x1||tree[k].mn[1]>y2||tree[k].mx[1]<y1) return;
    if (tree[k].mn[0]>=x1&&tree[k].mx[0]<=x2&&tree[k].mx[1]<=y2&&tree[k].mn[1]>=y1) 
    {
        tree[k].tag=tree[k].col=c; 
        return;
    }
    pushdown(k);
    if (tree[k].d[0]>=x1&&tree[k].d[0]<=x2&&tree[k].d[1]>=y1&&tree[k].d[1]<=y2) tree[k].col=c;
    if (ls[k]) change(ls[k]); 
    if (rs[k]) change(rs[k]);
}
inline int query(int x)
{
    int now=x,top=0;
    while (tree[now].fa) stack[++top]=now=tree[now].fa;
    while (top) pushdown(stack[top--]);
    return tree[x].col;
}
int main()
{
//  freopen("g.in","r",stdin);
//  freopen("g1.out","w",stdout);

    for (int i=0;i<=1;i++)
        tree[0].mn[i]=inf,tree[0].mx[i]=-inf;
    int testcase=read();
    while (testcase--)
    {
        n=read(),c=read(),q=read(); cnt=0; ans=0;
        memset(head,0,sizeof(head));
        for (int i=2;i<=n;i++)
            insert(read(),i);
        dfs(1);
        build(root,1,n,0,0);
//      for (int i=1;i<=n;i++)
//          printf("%d %d %d %d\n",tree[i].mx[0],tree[i].mx[1],tree[i].mn[0],tree[i].mn[1]);
//      for (int i=1;i<=n;i++)
//          printf("%d ",tree[i].fa);
        for (int i=1;i<=q;i++)
        {   
            a=read(); l=read(); c=read();
            if (!c) ans=(1ll*query(id[a])*i+ans)%mod;
            else
            {
                x1=in[a]; x2=out[a]; y1=deep[a]; y2=deep[a]+l;
                change(root);
            }
        }

        cout << ans << endl;
    }
    return 0;
}               
先展示下效果 https://pan.quark.cn/s/a4b39357ea24 遗传算法 - 简书 遗传算法的理论是根据达尔文进化论而设计出来的算法: 人类是朝着好的方向(最优解)进化,进化过程中,会自动选择优良基因,淘汰劣等基因。 遗传算法(英语:genetic algorithm (GA) )是计算数学中用于解决最佳化的搜索算法,是进化算法的一种。 进化算法最初是借鉴了进化生物学中的一些现象而发展起来的,这些现象包括遗传、突变、自然选择、杂交等。 搜索算法的共同特征为: 首先组成一组候选解 依据某些适应性条件测算这些候选解的适应度 根据适应度保留某些候选解,放弃其他候选解 对保留的候选解进行某些操作,生成新的候选解 遗传算法流程 遗传算法的一般步骤 my_fitness函数 评估每条染色体所对应个体的适应度 升序排列适应度评估值,选出 前 parent_number 个 个体作为 待选 parent 种群(适应度函数的值越小越好) 从 待选 parent 种群 中随机选择 2 个个体作为父方和母方。 抽取父母双方的染色体,进行交叉,产生 2 个子代。 (交叉概率) 对子代(parent + 生成的 child)的染色体进行变异。 (变异概率) 重复3,4,5步骤,直到新种群(parentnumber + childnumber)的产生。 循环以上步骤直至找到满意的解。 名词解释 交叉概率:两个个体进行交配的概率。 例如,交配概率为0.8,则80%的“夫妻”会生育后代。 变异概率:所有的基因中发生变异的占总体的比例。 GA函数 适应度函数 适应度函数由解决的问题决定。 举一个平方和的例子。 简单的平方和问题 求函数的最小值,其中每个变量的取值区间都是 [-1, ...
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值