BZOJ 8843 染色 [树链剖分+区间线段树]

简化神经元模型6 -- Hindmarsh-Rose Model 简化神经元模型 6 Hindmarsh-Rose Model 阅读详情

Description

给定一棵有n个节点的无根树和m个操作,操作有2类:

1、将节点a到节点b路径上所有点都染成颜色c;

2、询问节点a到节点b路径上的颜色段数量(连续相同颜色被认为是同一段),如“112221”由3段组成:“11”、“222”和“1”。

请你写一个程序依次完成这m个操作。


题意:给出一个树,树上每个点有颜色,两种操作:

1)将路径,<X,Y> 上的点颜色全部改成C ;

2)询问路径<X,Y> 上的颜色段数,11221为3段。

解法:非常明显的树剖+线段树。

线段树部分,记Val[X]为X段区间的颜色段数,lx[],rx[]分别为此段左右端点颜色,bj[]为此段覆盖颜色的标记,若值0为没有标记,pushdown很简单,直接改val[]为1,bj下传即可,maintain时,只需要将左右儿子的val加到本身中,并且当左儿子最右端的颜色等于右儿子最左端的颜色,那么val减1。

树剖更改部分,很简单,直接改就可以了。

树剖询问部分,需要注意两端线段所代表的路径若是相邻,需要类似线段树维护时的处理,若上一段的最右端颜色等于下一段的最左端颜色,ans减1。


代码:

(我的代码里把提取区间模板化了,range[1...RN]是路径<X,Y>依此在序列中的区间,isr[]数组代表此段是否与树上路径的方向相反..模板化的代价是常数大了一点..跑了8000MS左右,写的比较仔细,最后1A,难以置信)

#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<math.h>
#include<iostream>
#include<stdlib.h>
#include<set>
#include<map>
#include<queue>
#include<vector>
#include<bitset>
#pragma comment(linker, "/STACK:1024000000,1024000000")
template <class T>
bool scanff(T &ret){ //Faster Input
    char c; int sgn; T bit=0.1;
    if(c=getchar(),c==EOF) return 0;
    while(c!='-'&&c!='.'&&(c<'0'||c>'9')) c=getchar();
    sgn=(c=='-')?-1:1;
    ret=(c=='-')?0:(c-'0');
    while(c=getchar(),c>='0'&&c<='9') ret=ret*10+(c-'0');
    if(c==' '||c=='\n'){ ret*=sgn; return 1; }
    while(c=getchar(),c>='0'&&c<='9') ret+=(c-'0')*bit,bit/=10;
    ret*=sgn;
    return 1;
}
#define inf 1073741823
#define llinf 4611686018427387903LL
#define PI acos(-1.0)
#define lth (th<<1)
#define rth (th<<1|1)
#define rep(i,a,b) for(int i=int(a);i<=int(b);i++)
#define drep(i,a,b) for(int i=int(a);i>=int(b);i--)
#define gson(i,root) for(int i=ptx[root];~i;i=ed[i].next)
#define tdata int testnum;scanff(testnum);for(int cas=1;cas<=testnum;cas++)
#define mem(x,val) memset(x,val,sizeof(x))
#define mkp(a,b) make_pair(a,b)
#define findx(x) lower_bound(b+1,b+1+bn,x)-b
#define pb(x) push_back(x)
using namespace std;
typedef long long ll;
typedef pair<int,int> pii;

#define NN 100100
int n,qn;
int ptx[NN],lnum,a[NN],sz[NN],b[NN];
int top[NN],pos[NN],pn,dep[NN],f[NN][20],son[NN];
struct edge{
    int v,next;
    edge(){}
    edge(int v,int next){
        this->v=v;
        this->next=next;
    }
}ed[NN*2];
void addline(int x,int y){
    ed[lnum]=edge(y,ptx[x]);
    ptx[x]=lnum++;
}
struct segtree{
    int val[NN*4],lx[NN*4],rx[NN*4],m,bj[NN*4];
    void maintain(int th){
        if(th>=m){
            val[th]=1;
            if(bj[th])lx[th]=rx[th]=bj[th];
        }
        else{
            if(bj[th]){
                val[th]=1;
                lx[th]=rx[th]=bj[th];
            }
            else{
                val[th]=val[lth]+val[rth];
                lx[th]=lx[lth];
                rx[th]=rx[rth];
                if(rx[lth]==lx[rth])val[th]--;
            }
        }
    }
    void pushdown(int th){
        if(bj[th]){
            bj[lth]=bj[rth]=bj[th];
            bj[th]=0;
        }
    }
    void build(int n){
        for(m=1;m<n+3;m<<=1);
        rep(i,1,m<<1)bj[i+m]=0;
        rep(i,1,n)bj[i+m]=b[i];
        drep(i,m*2-1,1)maintain(i);
    }
    void update(int l,int r,int ql,int qr,int th,int v){
        if(l>=ql&&r<=qr)bj[th]=v;
        else{
            pushdown(th);
            int m=(l+r)>>1;
            if(ql<=m)update(l,m,ql,qr,lth,v);
            else maintain(lth);
            if(qr>m)update(m+1,r,ql,qr,rth,v);
            else maintain(rth);
        }
        maintain(th);
    }
    int lc,rc;
    int query(int l,int r,int ql,int qr,int th){
        int sum=0;
        if(l>=ql&&r<=qr){
            maintain(th);
            if(l==ql)lc=lx[th];
            else if(rc==lx[th])sum=-1;
            rc=rx[th];
            return sum+val[th];
        }
        else{
            pushdown(th);
            int m=(l+r)>>1;
            if(ql<=m)sum+=query(l,m,ql,qr,lth);
            else maintain(lth);
            if(qr>m)sum+=query(m+1,r,ql,qr,rth);
            else maintain(rth);
        }
        maintain(th);
        return sum;
    }
}st;
int lca(int x,int y){
    if(dep[x]<dep[y])swap(x,y);
    drep(i,16,0)if(dep[f[x][i]]>=dep[y])x=f[x][i];
    if(x==y)return x;
    drep(i,16,0)if(f[x][i]!=f[y][i])x=f[x][i],y=f[y][i];
    return f[x][0];
}
int getson(int x,int fa){
    int maxsz=0;
    son[x]=0;sz[x]=1;
    f[x][0]=fa;
    dep[x]=dep[fa]+1;
    gson(i,x){
        int y=ed[i].v;
        if(y==fa)continue;
        sz[x]+=getson(y,x);
        if(sz[y]>maxsz)maxsz=sz[y],son[x]=y;
    }
    return sz[x];
}
void getchain(int r,int x,int fa){
    pos[x]=++pn;
    top[x]=r;
    if(son[x])getchain(r,son[x],x);
    gson(i,x){
        int y=ed[i].v;
        if(y==fa||y==son[x])continue;
        getchain(y,y,x);
    }
}
int zh[NN];
void init(int n){
    lnum=pn=0;
    rep(i,1,n)ptx[i]=-1;
    rep(i,1,n)scanff(a[i]);
    rep(i,1,n-1){
        int x,y;
        scanff(x);scanff(y);
        addline(x,y);
        addline(y,x);
    }
    getson(1,0);
    getchain(1,1,0);
    rep(k,1,16)
    rep(i,1,n)f[i][k]=f[f[i][k-1]][k-1];
    rep(i,1,n)zh[pos[i]]=i;
    rep(i,1,n)b[pos[i]]=a[i];
    st.build(n);
}
char op[11];

int rn,rxn,ryn;
int isr[222];
pair<int,int> range[222],rangex[222],rangey[222];
void getrange(int x,int y){
    rn=rxn=ryn=0;
    int z=lca(x,y);
    while(top[x]!=top[z]){
        rangex[++rxn]=mkp(pos[top[x]],pos[x]);
        x=f[top[x]][0];
    }
    if(pos[z]+1<=pos[x])rangex[++rxn]=mkp(pos[z]+1,pos[x]);
    x=y;
    while(top[x]!=top[z]){
        rangey[++ryn]=mkp(pos[top[x]],pos[x]);
        x=f[top[x]][0];
    }
    rangey[++ryn]=mkp(pos[z],pos[x]);
    rep(i,1,rxn)range[++rn]=rangex[i],isr[rn]=1;
    drep(i,ryn,1)range[++rn]=rangey[i],isr[rn]=0;
}

int main(){
    int x,y,v;
    while(scanf("%d%d",&n,&qn)!=EOF){
        init(n);
        rep(i,1,qn){
            scanf("%s",op);
            scanff(x);scanff(y);
            getrange(x,y);
            if(op[0]=='C'){
                scanff(v);
                rep(j,1,rn){
                    int l=range[j].first;
                    int r=range[j].second;
                    st.update(0,st.m-1,l,r,1,v);
                }
            }
            if(op[0]=='Q'){
                int curlc,prerc,ans=0;
                rep(j,1,rn){
                    int l=range[j].first;
                    int r=range[j].second;
                    v=st.query(0,st.m-1,l,r,1);
                    ans+=v;
                    curlc=isr[j]?st.rc:st.lc;
                    if(j>1)if(curlc==prerc)ans--;
                    prerc=isr[j]?st.lc:st.rc;
                }
                printf("%d\n",ans);
            }
        }
    }
}








GPU架构-SIMT 本文深度剖析了GPU的SIMT架构,从硬件实现层面解析其与SIMD的本质差异。SIMT通过将32个线程捆绑为warp执行,在标量编程模型下实现数据并行。文章对比了SIMD和SIMT的执行模型、分支处理机制及存储层次,指出SIMT是对SIMD的虚拟化抽象。重点分析了Volta架构引入的独立线程调度技术,以及访存合并对性能的关键影响。通过定量数据展示了各代GPU架构的寄存器文件规模和线程调度机制,为开发者优化GPU程序提供了硬件层面的理论基础。 阅读详情

相关推荐

Faster Planner——Kinodynamic Astar详解

实际成本和启发式成本 实际成本 Actual Cost   每条轨迹的真实代价函数定义如下: J(T)=∫0T∥u(t)∥2dt+ρT \mathcal{J}(T)=\int_{0}^{T}\|\mathbf{u}(t)\|^{2} d t+\rho T J(T)=∫0T​∥u(t)∥2dt+ρT 离散形式下: 启发成本 Heuristic Cost pμ∗(t)=16αμt3+12βμt2+vμc+pμc=pμc+vμc+T2∗((2∗vμc−2∗vμg)/(2∗T)−(6∗pμc−6∗pμg+6∗T∗v

漫长IT路 4835

线段树(区间树)之区间染色和4n推导过程

  前言   线段树(区间树)是什么呢?有了二叉树、二分搜索树,线段树又是干什么的呢?最经典的线段树问题:区间染色;正如它的名字而言,主要解决区间的问题   一、线段树说明   1、什么是线段树?   线段树首先是二叉树,并且是平衡二叉树(它是一 棵空树或它的左右两个子树的高度差的绝对值不超过1,并且左右两个子树都是一棵平衡二叉树),并且具有二分性质。 如下图,就是一颗线段树:    ...

weixin_30898109的博客 392

Linux CentOS7文件系统(/dev/var)的容量扩充

原因是之前安装docker后,再想安装Nessus,系统说home、var文件系统的内存都不够。

JHoanna的博客 3226

poj2777线段树区间染色

网上的代码有很多但是实现的方式不同,我个人还是比较喜欢带结构体的线段树, 然后本题的关键就在于维护颜色的问题上了, 结构体中的2个变量sum表示是第几种颜色,初始化为1 lazy表示之前是否染过色 如果染过色就把染过的色下传,然后在进行染色 然后就是判断这个点所代表区间的颜色,如果左右区间颜色不同,就令他的颜色为-1,相同就等于左右区间的颜色。 #include<iost...

qq_42759120的博客 295

第15章 AI 产品原型设计 —— 让 AI 成为你的产品经理

理解产品需求- 将模糊的想法转化为具体的原型方案生成高质量原型- 输出符合设计规范的 HTML 原型提供设计建议- 基于 UX 最佳实践给出优化建议维护原型文档- 自动更新原型说明和变更记录。

快乐的修补匠的专栏 506

Anomalib库安装以及使用

Anomalib是一个专注于异常检测的深度学习库。它的目标是收集最新的异常检测算法,并提供用于在公共和私有数据集上进行基准测试的工具。该库提供了一系列已实现的异常检测算法,这些算法在最近的文献中有所描述。此外,Anomalib还提供了一套工具,方便开发人员开发和实现自定义模型。该库特别注重基于图像的异常检测,旨在识别数据集中的异常图像或图像中的异常像素区域。通过使用Anomalib,用户可以快速构建和评估各种异常检测算法,以满足其特定需求。

mingo_敏 5201

线段树进阶-染色问题 附poj-2777题解

区域染色覆盖问题 假设某大学有一面文化墙,各个学院都可以在上面涂色,要求涂色区域高必须和墙一样,宽度任意但必须是整数(以米为单位)。涂色可以覆盖其他学院的涂色。现在若干个学院涂色之后最终这面墙上能看见多少种颜色。 这就是简单的染色问题了。当然有很多种不同的说法,但整体上离不开这两个问题:1.区域覆盖。2.多种染色方式。既然是区域操作,那么用线段树是比较合理了。用...

iwts 5374

2023 数字IC设计秋招复盘——数十家公司笔试题、面试实录

由于是本人的亲身经历,所以想通过付费专栏获得一些收益。扣除平台的抽成后,我会将最终收益的一半捐献给贫困山区助学基金。专栏内容: 1. 几十场笔试真题的原题纯净版与个人解答版。 2. 几十场面试实录,包含提问、解答与个人复盘建议。 3. 个人整理的知识点总结。 4. 求职准备、简历制作方面的建议。

w0shishabi的博客 1万+

HYSBZ 2243 染色 (树链剖分)

树链剖分

Muti-Agent 2822

Git救援:如何从误操作中恢复未提交的更改

摘要:本文探讨了误操作git reset --hard导致未提交更改丢失后的恢复方法。首先分析git reflog的局限性,随后介绍利用IDE本地历史记录(如IntelliJ IDEA和VS Code)进行文件恢复的具体步骤。最后建议使用文件系统恢复工具(如Linux的extundelete或Windows的Recuva)作为备选方案。文章强调定期提交的重要性,同时提供了意外发生时可行的恢复策略,帮助开发者尽可能挽回丢失的工作内容。(149字)

2501_90323865的博客 129

QNX系统中的密码哈希格式——数据安全深度分析

综上所述,QNX系统中的Shadowed密码哈希格式提供了一种有效的数据安全机制,能够保护用户密码的安全性。通过将用户密码的哈希值存储在系统文件中,并结合哈希算法和盐值的使用,可以有效地防止明文密码泄露和密码破解。密码哈希是一种常用的安全技术,用于将用户密码转换为不可逆的哈希值,以保护用户的敏感信息。在QNX操作系统中,存在一种称为Shadowed密码哈希格式的机制,用于存储用户密码的安全散列值。当用户登录系统时,系统会将用户输入的密码与保存的哈希值进行比对,以验证密码的正确性。在上述代码中,首先使用。

UneDatabase的博客 253

嘿嘿嘿嘿的 zy 树链剖分+线段树+树上带修莫队

题意 给一颗 n 个点的树,每一个点有一个颜色,然后维护几个操作。 操作 1:t=1 时,将 x 点的颜色修改为 y 操作 2:t=2 时,询问 x 到 y 路径上有多少个不同的颜色段 操作 3:t=3 时,询问 x 到 y 路径上的出现次数最多的颜色的出现次数 操作2是[SDOI2011]染色原题 操作3是树上带修莫队,关于如何求出出现次数最多的颜色出现次数,考虑到时莫队做法,一次只能+1或-1...

wty的博客 625

Camera2Demo

在Camera2 的基础上进行封装,使得Camera2一堆初始化逻辑与Activity分离,降低耦合度,完成预览拍照并保存的操作

bzoj5404 party 树链剖分+bitset

Description Solution 我好弱啊,第一档分都没拿到手orz 首先看清题意,这是一个有向图 一个朴素的想法就是我们倍增记录rec[i,j]表示i向上2^k层后包含节点颜色的bitset,m只有1k 注意到这样非常慢,考虑轻重链剖分的做法。我们记录rec[i]为i到链顶节点包含颜色的bitset,对于不满一整条链的我们用线段树查询,这样可以做到一个log...

olahiuj的博客 249

大中型超市收银系统(可直接运行)

光步前台收银系统系统功能:商品销售、商品退货、挂单、收银员权限、会员销售、单品取消、整单取消、商品查询、脱机销售、脱机数据上传,基本资料下载,开钱箱、小票打印、收款结算,支持多币种付款方式(现金、储值卡、礼券、微信等),支持多种促销。运行环境:.net 4.0登陆信息用户名:1001 密码:123456内置商品信息,商品编码可输入00001000 - 00010000,测试效果相关功能键F5 结算 F9挂单 F11商品查询 F8退货 Insert单品取消 Del整单取消 F12开钱箱F2 会员 Ctrl+Z退出系统 Home 锁屏 相关源码待公开

ET2012新版免狗免安装绿色软件

ET2012新版免狗免安祖昂绿色软件。,新界面,新视觉,

奇怪的树 - BIT - 树剖

题目大意:给一颗有根树,每个点是黑色或者白色,支持:翻转一个点的颜色,翻转所有与给定点距离为奇数的点的颜色,求所有黑点与给定点的lca的编号之和。2e5。 题解:首先考虑没有2咋做,类似与动态dp,先树剖一下,然后每个点维护轻边的所有信息,询问的时候有点像是LCT的切换轻重边。考虑如果是翻转整个树的颜色咋做,显然不仅维护黑点同时维护白点的答案,每次翻转整棵树就直接交换两个数组。因为还有距离为奇数...

Mys_C_K的博客 487

复分析 阿尔福斯(Ahlfors) 第三版答案 英文

答案分为十章,有部分习题没有答案,全英文复分析阿尔福斯(Ahlfors) 第三版答案

【树链剖分】【Hall定理】[JZOJ5824][BZOJ5404] Party

Description Solution 我们发现颜色种类不多,只有1000种 因此我们可以用bitset来维护颜色集合。 我们将这棵树轻重链剖分,用线段树维护链的颜色集合(空间为O(N*1000/32)),若倍增的话空间要多乘上log。 当我们需要查询一条链时,由于没有修改,我们大可以直接记录每个点到所在重链顶的颜色集合,这样原本log^2的时间复杂度就变成log的了。 ...

Never give in. 367

线段树 ---- 染色问题

Mayor's posters 线段树染色问题 法一 :线段树 + 离散化: 1e+7的区间范围太大了,硬刚的话就是tle或者mle,所以用到了离散化的思想 新的覆盖旧的,问最后又多少张海报会露出来,可见没法用线段树的push_up操作,我们在染色时,就是让线段树中对应一个区间的节点做一个颜色标记,然后push_bown,向下染色。 查询的时候,用hash的思想,我开了一个use数组来表示这个颜色计算过没有,我们查询的是整个区间,所以在查询的过程中,如果一个节点的颜色没有被计算进去,则ans++.

IsayIwant的博客 838

线段树基础之区间染色ZOJ1610

Count the colors 参考博客:https://blog.youkuaiyun.com/nb_weige/article/details/98779241 区间染色,由于下一个颜色会覆盖原有的颜色,其实就是线段树的区间更新问题,但是这个更新问题更加复杂一点,还让你求出每一个颜色一共出现了几段,那就得多加一个col记录上一个的颜色,多一个ans数组记录颜色出现次数 细节: 这里的数字代表的不是区间标...

想要一只银渐层 379

poj1436(线段树区间染色)

Horizontally Visible SegmentsThere is a number of disjoint vertical line segments in the plane. We say that two segments are horizontally visible if they can be connected by a horizontal line segment t

siyu 523

poj 2777 Count Color 【线段树lazy区间染色 + 查询区间颜色数目 + 状态压缩】

Count Color Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 39950   Accepted: 12050 Description Chosen Problem Solving and Program design as an optional cour

世界很大 1385

POJ 1436 Horizontally VisibleSegments(线段树:区间覆盖染色)

POJ 1436 Horizontally VisibleSegments(线段树:成段更新+区间开闭) 分析: 1.    首先读入所有的线段,然后按x轴坐标从小到大排序,然后我们一次处理每条线段,用一个二维矩阵mark[i][j]保存第i条线段和第j条线段之间的关系.(如果相互可以看到,则mark为true,否则为false).   2.    下面的问题是如果求出任意两线段之间的可见

code 1600

线段树染色问题(区间一共有多少种不同颜色)poj2777

  描述 选择问题解决和程序设计作为选修课程,您需要解决各种问题。在这里,我们遇到了一个新问题。  有一个很长的板长L厘米,L是正整数,所以我们可以将板均分为L段,从左到右标记为1,2,...... L,每个为1厘米长。现在我们必须为电路板上色 - 只有一种颜色的一个部分。我们可以在电路板上执行以下两项操作: 1。“CAB C”将电路板从A段染色到B段,颜色为C.  2.“PA B”输出A段和...

qq_40859951的博客 1057

TyvjOJ题目 P1473 校门外的树3(线段树区间染色种类数不覆盖)

P1473 校门外的树3 时间: 1000ms / 空间: 131072KiB / Java类名: Main 描述  校门外有很多树,有苹果树,香蕉树,有会扔石头的,有可以吃掉补充体力的…… 如今学校决定在某个时刻在某一段种上一种树,保证任一时刻不会出现两段相同种类的树,现有两个操作: K=1,读入l,r表示在l~r之间种上的一种树 K=2,读入l,r表示询问l~r之间

Jogging_Clown 1208

ZOJ16109线段树区间操作(区间染色)

题面 Painting some colored segments on a line, some previously painted segments may be covered by some the subsequent ones. Your task is counting the segments of different colors you can see at last. Input The first line of each data set contains exactly one

qq_35687225的博客 367

poj 2777 线段树(区间染色)

题意:给一个固定长度为L的画板。有两个操作:1、C A B C:区间AB内涂上颜色C。2、P A B:查询区间AB内颜色种类数。 思路:区间显然要用线段树。颜色因为不超过30,所以可以用位运算。关键在于优化:每次更新到完整区间的时候标记一下,不更新到叶子节点,当后面更新或者查询需要用到比这个区间小的区间的时候再往下带。 #include #include #include using n

dearmango 518

线段树区间染色 浮水法 学习小记 Poj 2777 + Poj 2528

复习过的东西必须时常拿来练练,虽说都是水题。。。。 Poj 2777 典型的区间染色问题,貌似我的写法为了不数组越界必须多开一倍的数组空间。。。。。还没有想到解决方法,有机会参考一下别人的写法。 Poj 2528 和上面那道差不多,用线段树写的时候用了STL里的map进行离散化,因为不可能开出10000000*4大小的数组。 我的代码在poj过不了,看discuss里面有人说测试数据有问题…

whyorwhnt的专栏 1863

Count Color(线段树区间染色)

题目链接: Count Color 大致题意 有n个位置, 从1~n标号, 有两种操作: ​ ① C l r c 把区间[l, r]染色为c ​ ②P l r 询问[l, r]区间有多少种颜色. 解题思路 线段树区间染色 我拿到这题后, 这题不是傻逼题吗? 然后写了3h 其实以前我是有博客写过关于线段树区间染色问题的, 博客链接我们只需要用一个懒标记表示当前区间是什么颜色即可, 每次更新的时候, 我们都下放懒标记, 查询的时候不需要下放懒标记. 那么这个题我为什么做了这么久呢? (原因是网上的博客的写法都和

Fau的博客 1261
上一篇: SPOJ QTREE Query on a tree [树链剖分+线段树]
下一篇: HDU 5293 Tree chain problem [树链剖分+线段树+树形DP]
GrassTreeFlower
博客等级 码龄11年 14粉丝 116原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值