UOJ 58 [WC2013]糖果公园

本文详细介绍了树上莫队算法的实现细节,并通过具体代码示例解释了如何正确运用该算法解决复杂问题。作者分享了一次有趣的调试经历,强调了初始化的重要性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

树上莫队

题解详见VFK大爷的 :
http://vfleaking.blog.163.com/blog/static/174807634201311011201627/

orz vfleaking orz vfleaking orz vfleaking orz vfleaking

这题在本机对拍的时候,忘记在分块里面初始化1,导致所有节点都没有进行分块操作。结果自己拍大数据跑的贼快,大点都只要一秒不到???(可能是因为数据随机?原因成谜。。。)然后非常喜悦 地交上去就T光光了。

真是一段有趣的经历- -

#include<cstdio>
#include<cstring>
#include<algorithm>
#define ll long long
#define reg register
#define N 100005
#define SIZE 2154
#define getc() (S == T && (T = (S = B) + fread(B, 1, 1<<23, stdin), S == T) ? 0 : *S++)
using namespace std;
char B[1<<23], *S = B, *T = B;
bool vis[N];
ll ans, print[N], v[N];
int bin[20], col[N], w[N], last[N], que[N], belong[N], siz[N], block, fa[N][20], dep[N], tot[N];
struct edge{int next,to;}e[N<<1];int ecnt;
struct query{int x, y, t, id;}q[N];int qcnt;
struct change{int x, from, to;}c[N];int ccnt;
int in()
{
    reg int r = 0;
    reg char c = getc();
    while(c<'0'||c>'9')c=getc();
    while(c>='0'&&c<='9')r=r*10+c-'0',c=getc();
    return r;
}
bool cmp(query a, query b)
{
    if(belong[a.x]==belong[b.x] && belong[a.y]==belong[b.y])return a.t<b.t;
    else if(belong[a.x]==belong[b.x])return belong[a.y]<belong[b.y];
    else return belong[a.x]<belong[b.x];
}
void addedge(int a, int b)
{
    e[++ecnt]=(edge){last[a],b};
    last[a]=ecnt;
} 
void addnode(int x, int f)
{
    if(siz[belong[f]]<SIZE)
        belong[x]=belong[f];
    else
        belong[x]=++block;
    siz[belong[x]]++;
}
void makeblock()
{
    que[0]=belong[1]=siz[1]=block=1;
    for(int head=0, tail=1; head<tail; head++)
    {
        int x=que[head];
        for(int i = last[x]; i; i=e[i].next)
        {
            int y=e[i].to;
            if(belong[y])continue;
            que[tail++]=y;
            addnode(y,x);
        }
    }
}
void dfs(int x)
{
    dep[x]=dep[fa[x][0]]+1;
    for(int i = 1; bin[i]<=dep[x]; i++)
        fa[x][i]=fa[fa[x][i-1]][i-1];
    for(int i = last[x]; i; i=e[i].next)
    {
        int y=e[i].to;
        if(y==fa[x][0])continue;
        fa[y][0]=x;
        dfs(y);
    }
}
void reverse(int x)
{
    if(vis[x])ans-=w[tot[col[x]]]*v[col[x]], tot[col[x]]--;
    else tot[col[x]]++, ans+=w[tot[col[x]]]*v[col[x]];
    vis[x]=!vis[x];
}
void make(int x, int y)
{
    while(x!=y)
    {
        if(dep[x]>dep[y])reverse(x), x=fa[x][0];
        else reverse(y), y=fa[y][0];
    }
}
void turn(int x, int y)
{
    if(vis[x])
    {
        ans-=w[tot[col[x]]]*v[col[x]];
        tot[col[x]]--;
        tot[y]++;
        ans+=w[tot[y]]*v[y]; 
    }
    col[x]=y;
}
int lca(int x, int y)
{
    if(dep[x]<dep[y])swap(x,y);
    int t = dep[x]-dep[y];
    for(int i = 0; bin[i]<=t; i++)
        if(t&bin[i])
            x=fa[x][i];
    for(int i = 19; i>=0; i--)
    {
        if(fa[x][i]!=fa[y][i])
            x=fa[x][i], y=fa[y][i];
    }
    return x==y?x:fa[x][0];
}
int main()
{
    int n=in(), m=in(), Q=in();
    bin[0]=1;
    for(int i = 1; i < 20; i++)
        bin[i]=bin[i-1]<<1;
    for(int i = 1; i <= m; i++)
        v[i]=in();
    for(int i = 1; i <= n; i++)
        w[i]=in();
    for(int i = 1, a, b; i < n; i++)
    {
        a=in(); b=in();
        addedge(a,b);
        addedge(b,a);
    }
    for(int i = 1; i <= n; i++)
        col[i]=in();
    makeblock();
    dfs(1);
    for(int i = 1; i <= Q; i++)
    {
        int op=in(), x=in(), y=in();
        if(op==0)
        {
            c[++ccnt]=(change){x,col[x],y};
            col[x]=y;
        }
        else
        {
            if(x>y)swap(x,y);
            q[++qcnt]=(query){x,y,ccnt,qcnt};
        }
    }
    sort(q+1,q+1+qcnt,cmp);
    make(q[1].x,q[1].y);
    for(;ccnt<q[1].t;ccnt++)
        turn(c[ccnt+1].x, c[ccnt+1].to);
    for(;ccnt>q[1].t;ccnt--)
        turn(c[ccnt].x, c[ccnt].from);
    int t=lca(q[1].x,q[1].y);
    reverse(t); 
    print[q[1].id]=ans;
    reverse(t);
    for(int i = 2; i <= qcnt; i++)
    {
        for(;ccnt<q[i].t;ccnt++)
            turn(c[ccnt+1].x, c[ccnt+1].to);
        for(;ccnt>q[i].t;ccnt--)
            turn(c[ccnt].x, c[ccnt].from);
        make(q[i].x,q[i-1].x);
        make(q[i].y,q[i-1].y);
        int temp=lca(q[i].x,q[i].y);
        reverse(temp);
        print[q[i].id]=ans;
        reverse(temp);
    }
    for(int i = 1; i <= qcnt; i++)
        printf("%lld\n",print[i]);
} 
内容概要:本文深入探讨了Kotlin语言在函数式编程和跨平台开发方面的特性和优势,结合详细的代码案例,展示了Kotlin的核心技巧和应用场景。文章首先介绍了高阶函数和Lambda表达式的使用,解释了它们如何简化集合操作和回调函数处理。接着,详细讲解了Kotlin Multiplatform(KMP)的实现方式,包括共享模块的创建和平台特定模块的配置,展示了如何通过共享业务逻辑代码提高开发效率。最后,文章总结了Kotlin在Android开发、跨平台移动开发、后端开发和Web开发中的应用场景,并展望了其未来发展趋势,指出Kotlin将继续在函数式编程和跨平台开发领域不断完善和发展。; 适合人群:对函数式编程和跨平台开发感兴趣的开发者,尤其是有一定编程基础的Kotlin初学者和中级开发者。; 使用场景及目标:①理解Kotlin中高阶函数和Lambda表达式的使用方法及其在实际开发中的应用场景;②掌握Kotlin Multiplatform的实现方式,能够在多个平台上共享业务逻辑代码,提高开发效率;③了解Kotlin在不同开发领域的应用场景,为选择合适的技术栈提供参考。; 其他说明:本文不仅提供了理论知识,还结合了大量代码案例,帮助读者更好地理解和实践Kotlin的函数式编程特性和跨平台开发能力。建议读者在学习过程中动手实践代码案例,以加深理解和掌握。
内容概要:本文深入探讨了利用历史速度命令(HVC)增强仿射编队机动控制性能的方法。论文提出了HVC在仿射编队控制中的潜在价值,通过全面评估HVC对系统的影响,提出了易于测试的稳定性条件,并给出了延迟参数与跟踪误差关系的显式不等式。研究为两轮差动机器人(TWDRs)群提供了系统的协调编队机动控制方案,并通过9台TWDRs的仿真和实验验证了稳定性和综合性能改进。此外,文中还提供了详细的Python代码实现,涵盖仿射编队控制类、HVC增强、稳定性条件检查以及仿真实验。代码不仅实现了论文的核心思想,还扩展了邻居历史信息利用、动态拓扑优化和自适应控制等性能提升策略,更全面地反映了群体智能协作和性能优化思想。 适用人群:具备一定编程基础,对群体智能、机器人编队控制、时滞系统稳定性分析感兴趣的科研人员和工程师。 使用场景及目标:①理解HVC在仿射编队控制中的应用及其对系统性能的提升;②掌握仿射编队控制的具体实现方法,包括控制器设计、稳定性分析和仿真实验;③学习如何通过引入历史信息(如HVC)来优化群体智能系统的性能;④探索中性型时滞系统的稳定性条件及其在实际系统中的应用。 其他说明:此资源不仅提供了理论分析,还包括完整的Python代码实现,帮助读者从理论到实践全面掌握仿射编队控制技术。代码结构清晰,涵盖了从初始化配置、控制律设计到性能评估的各个环节,并提供了丰富的可视化工具,便于理解和分析系统性能。通过阅读和实践,读者可以深入了解HVC增强仿射编队控制的工作原理及其实际应用效果。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值