首页 > 其他分享 >做题记录:P2146 [NOI2015] 软件包管理器

做题记录:P2146 [NOI2015] 软件包管理器

时间:2022-08-25 11:57:19浏览次数:71  
标签:P2146 管理器 int siz void top son NOI2015 id

树剖模板题,要求的操作时候区间平推,区间和查询。

这还不简单?我会珂朵莉树!

然而我打了珂线段树:

直接一发A掉。

#include<cstdio>
#include<algorithm>
#include<cmath>
#define N 1919810
#define lc p<<1
#define rc p<<1|1 
using namespace std;
int n,m,rt=1919000;
int head[N],to[N],nxt[N],tot,id[N],son[N],f[N],idx,siz[N],dep[N],top[N];
void add(int u,int v){
    to[++tot]=v;
    nxt[tot]=head[u];
    head[u]=tot;
}
struct Segement_tree{
    int l,r,val,tag;
}s[8*N];
void build(int p,int l,int r){
    s[p].l=l,s[p].r=r;s[p].tag=-1;
    if(l==r)return;
    build(lc,l,(l+r)/2);
    build(rc,(l+r)/2+1,r);
}
void pushup(int p){s[p].val=s[lc].val+s[rc].val;}
void pushdown(int p){
    if(s[p].tag==-1)return;
    s[lc].tag=s[p].tag;s[rc].tag=s[p].tag;
    s[lc].val=s[p].tag*(s[lc].r-s[lc].l+1);
    s[rc].val=s[p].tag*(s[rc].r-s[rc].l+1);
    s[p].tag=-1; 
} 
void assign(int p,int l,int r,int v){
    if(s[p].l>r||s[p].r<l)return;
    if(s[p].l>=l&&s[p].r<=r){
        s[p].val=v*(s[p].r-s[p].l+1);
        s[p].tag=v;
        return;
    }
    pushdown(p);
    assign(lc,l,r,v);assign(rc,l,r,v);
    pushup(p);
}
int query(int p,int l,int r){
    if(s[p].l>r||s[p].r<l)return 0;
    if(s[p].l>=l&&s[p].r<=r)return s[p].val;
    pushdown(p);
    return query(lc,l,r)+query(rc,l,r);
}
void dfs1(int x,int fa){
    dep[x]=dep[fa]+1;siz[x]=1;f[x]=fa;
    int maxn=-1;
    for(int i=head[x];i;i=nxt[i]){
        int y=to[i];
        if(y==fa)continue;
        dfs1(y,x);
        siz[x]+=siz[y];
        if(siz[y]>maxn)maxn=siz[y],son[x]=y;
    }
}
void dfs2(int x,int topx){
    id[x]=++idx,top[x]=topx;
    if(!son[x])return;
    dfs2(son[x],topx);
    for(int i=head[x];i;i=nxt[i]){
        int y=to[i];
        if(y==f[x]||y==son[x])continue;
        dfs2(y,y);
    }
}
void change(int x,int y,int v){
    while(top[x]!=top[y]){
        //printf("%d\n",x);
        if(dep[top[x]]<dep[top[y]])swap(x,y);
        assign(1,id[top[x]],id[x],v);x=f[top[x]];
    }
    if(dep[x]>dep[y])swap(x,y);
    assign(1,id[x],id[y],v);
}
void assub(int x,int v){assign(1,id[x],id[x]+siz[x]-1,v);}
signed main(){
    scanf("%d",&n);
    for(int i=1;i<n;i++){
        int a;
        scanf("%d",&a);
        if(a==0)a=rt;
        add(i,a);add(a,i);
    }dfs1(rt,rt);dfs2(rt,rt);
    build(1,1,idx);
    scanf("%d",&m);
    while(m--){
        char s[26];
        int a;
        scanf("%s%d",s,&a);
        if(a==0)a=rt;
        if(s[0]=='i'){
            int yl=query(1,id[rt],id[rt]+siz[rt]-1);
            change(rt,a,1);
            printf("%d\n",abs(query(1,id[rt],id[rt]+siz[rt]-1)-yl));
        }else{
            int yl=query(1,id[rt],id[rt]+siz[rt]-1);
            assub(a,0);
            printf("%d\n",abs(query(1,id[rt],id[rt]+siz[rt]-1)-yl));
        }
    }
    return 0;
}

打完之后我心血来潮想试试珂朵莉树珂不珂以过:

#include<cstdio>
#include<algorithm>
#include<cmath>
#include<set>
#define N 1919810
#define ct Chtholly_tree
#define Chtholly set<ct>::iterator
using namespace std;
int n,m,rt=1919000;
int head[N],to[N],nxt[N],tot,id[N],son[N],f[N],idx,siz[N],dep[N],top[N];
void add(int u,int v){
    to[++tot]=v;
    nxt[tot]=head[u];
    head[u]=tot;
}
struct Chtholly_tree{
    int l,r;
    mutable int val;
    ct(int a=0,int b=0,int c=0){l=a,r=b,val=c;}
    bool operator <(const ct &c)const{return l<c.l;}
};
set<ct>st;
Chtholly split(int p){
    Chtholly it=st.lower_bound(ct(p,0,0));
    if(it!=st.end()&&it->l==p)return it;
    it--;ct tmp=*it;st.erase(it);
    st.insert(ct(tmp.l,p-1,tmp.val));
    return st.insert(ct(p,tmp.r,tmp.val)).first;
}
void assign(int l,int r,int v){
    Chtholly right=split(r+1),left=split(l);
    st.erase(left,right);
    st.insert(ct(l,r,v));
}
int query(int l,int r){
    Chtholly right=split(r+1),left=split(l);
    int ans=0;
    for(;left!=right;left++)ans+=left->val*(left->r-left->l+1);
    return ans;
}
void dfs1(int x,int fa){
    dep[x]=dep[fa]+1;siz[x]=1;f[x]=fa;
    int maxn=-1;
    for(int i=head[x];i;i=nxt[i]){
        int y=to[i];
        if(y==fa)continue;
        dfs1(y,x);
        siz[x]+=siz[y];
        if(siz[y]>maxn)maxn=siz[y],son[x]=y;
    }
}
void dfs2(int x,int topx){
    id[x]=++idx,top[x]=topx;
    if(!son[x])return;
    dfs2(son[x],topx);
    for(int i=head[x];i;i=nxt[i]){
        int y=to[i];
        if(y==f[x]||y==son[x])continue;
        dfs2(y,y);
    }
}
void change(int x,int y,int v){
    while(top[x]!=top[y]){
        if(dep[top[x]]<dep[top[y]])swap(x,y);
        assign(id[top[x]],id[x],v);x=f[top[x]];
    }
    if(dep[x]>dep[y])swap(x,y);
    assign(id[x],id[y],v);
}
void assub(int x,int v){assign(id[x],id[x]+siz[x]-1,v);}
signed main(){
    scanf("%d",&n);
    for(int i=1;i<n;i++){
        int a;
        scanf("%d",&a);
        if(a==0)a=rt;
        add(i,a);add(a,i);
    }dfs1(rt,rt);dfs2(rt,rt);
    st.insert(ct(0,2147483647,0));
    scanf("%d",&m);
    while(m--){
        char s[26];
        int a;
        scanf("%s%d",s,&a);
        if(a==0)a=rt;
        if(s[0]=='i'){
            int yl=query(id[rt],id[rt]+siz[rt]-1);
            change(rt,a,1);
            printf("%d\n",abs(query(id[rt],id[rt]+siz[rt]-1)-yl));
        }else{
            int yl=query(id[rt],id[rt]+siz[rt]-1);
            assub(a,0);
            printf("%d\n",abs(query(id[rt],id[rt]+siz[rt]-1)-yl));
        }
    }
    return 0;
}

冰冷的事实告诉我,这道题珂朵莉树只能得70分(TAT)。

在我巨大的提交次数上白白增加了2(

完结撒花(

标签:P2146,管理器,int,siz,void,top,son,NOI2015,id
From: https://www.cnblogs.com/masida-hall-LZ/p/16623823.html

相关文章

  • Activiti可视化流程管理器
    1.简介Activiti是一个业务流程管理(BPM)框架,它是覆盖了业务流程管理,工作流,服务协作等领域的一个开源,灵活的,易扩展的可执行流程语言框架。在Java工作流引擎中可谓是主流,我......
  • [Ynoi2015] 盼君勿忘
    题传世纪诈骗题首先,所有子序列分别去重的和的意思是什么?令可重集\(S\)为序列\(a_l,a_{l+1}\dotsa_r\)的所有子序契合。假设我们有一个序列\(T\),对\(T\)去重......
  • [Ynoi2015] 此时此刻的光辉
    题传做完CF1422F再做这道题就肥肠有感觉了。如果你不想再看一题那么我就无耻推销一下我的题解。\[\text{————————我是分割线————————}\]请确保你......
  • [Ynoi2015] 我回来了
    题传7个月后再来看这道题,还是感觉太妙了。由于答案最终输出\(E\timesLen\),所以本质上是问\(\foralld\in[L,R]\)的贡献和,再进一步想,亵渎的要求就是寻找序列\[x_......
  • [Ynoi2015] 即便看不到未来
    题传\(O(10n\logn)\)能过,居然不卡常,青结了。感觉是比较套路的一道Ynoi了qwq。首先看题目,需要找的就是一段长度为\(1\dots10\)的极长连续的(公差为1)的等差数......
  • 基础复习——数据库SQLite——SQL的基本语法——数据库管理器SQLiteDatabase——数据
                                                         ......
  • C# Winform在任务管理器中隐藏指定窗口
    业务环境需求:每次打开主窗体都需要进行登录验证,关闭主窗体只是最小化到系统托盘,并不是真正的退出程序,现关闭主窗体后发现任务管理器中还能找到主窗体的任务,然后能从......
  • NixOS & nixpkg包管理器使用体验
    更换国内镜像NixOS以优先选择镜像,备选源站为例,选择以下配置之一:单独安装的Nix:编辑配置文件添加或修改如下项(通常系统配置在 /etc/nix/nix.conf,用户配置在 ~/.confi......
  • 2022.8.14 NPM包管理器与Babel
    04、NPM包管理器4.1、简介官方网站:https://www.npmjs.com/ NPM全称NodePackageManager,是Node.js包管理工具,是全球最大的模块生态系统,里面所有的模块都是开源免费的;也......