zoukankan      html  css  js  c++  java
  • 魔法少女 LJJ——线段树

    题目

    【题目描述】

    在森林中见过会动的树,在沙漠中见过会动的仙人掌过后,魔法少女 LJJ 已经觉得自己见过世界上的所有稀奇古怪的事情了。

    LJJ 感叹道“这里真是个迷人的绿色世界,空气清新、淡雅,到处散发着醉人的奶浆味;小猴在枝头悠来荡去,好不自在;各式各样的鲜花争相开放,各种树枝的枝头挂满沉甸甸的野果;鸟儿的歌声婉转动听,小河里飘着落下的花瓣真是人间仙境”。

    SHY 觉得 LJJ 还是太 naive,一天, SHY 带着自己心爱的图找到 LJJ,对 LJJ 说:“既然你已经见识过动态树,动态仙人掌了,那么今天就来见识一下动态图吧”。

    LJJ:“要支持什么操作?”
    SHY:
    1. 新建一个节点,权值为 $x$。
    2. 连接两个节点。
    3. 将一个节点 $a$ 所属于的联通快内权值小于 $x$ 的所有节点权值变成 $x$。
    4. 将一个节点 $a$ 所属于的联通快内权值大于 $x$ 的所有节点权值变成 $x$。
    5. 询问一个节点 $a$ 所属于的联通块内的第 $k$ 小的权值是多少。
    6. 询问一个节点 $a$ 所属联通快内所有节点权值之积与另一个节点 $b$ 所属联通快内所有节点权值之积的大小。
    7. 询问 $a$ 所在联通块内节点的数量
    8. 若两个节点 $a$,$b$ 直接相连,将这条边断开。
    9. 若节点 $a$ 存在,将这个点删去。

    LJJ:“我可以离线吗?”
    SHY:“可以,每次操作是不加密的。”
    LJJ:“我可以暴力吗?”
    SHY:“自重。”

    LJJ很郁闷,你能帮帮他吗?


    【输入格式】

    第一行一个整数 $n$ ,代表岛屿数量。

    接下来 $n-1$ 行,每行三个整数 $u,v,w$ ,代表 $u$ 号岛屿和 $v$ 号岛屿由一条代价为 $c$ 的桥梁直接相连,保证 $1 le u,v le n$ 且 $1 le c le 100000 $ 。

    第 $n+1$ 行,一个整数 $m$ ,代表敌方机器能使用的次数。

    接下来 $m$ 行,每行一个整数 $k_i$ ,代表第 $i$ 次后,有 $k_i$ 个岛屿资源丰富,接下来 $k$ 个整数$h_1,h_2,…h_k$ ,表示资源丰富岛屿的编号。


    【输出格式】
    具体输出格式见样例 。
    【样例输入】

    12
    1 2
    1 3
    1 4
    1 5
    1 6
    2 1 2
    2 2 3
    2 3 4
    2 4 5
    9 1
    3 2 5
    5 3 4


    【样例输出】

    6


    【数据范围与提示】
    对 $100\%$ 的数据 $0le m le 400000,c le 7$,所有出现的数均 $le 1000000000$,所有出现的点保证存在.

    题解

    题目中 $ c leq 7 $,即说明仅有前 $ 7 $ 个操作

    对于操作一,新建一棵线段树,并插入这个点的值

    对于操作二,合并两颗线段树,用并查集维护

    对于操作三,查询个数并删除小于 $ x $ 的点,插入 $ x $

    对于操作四,类似三

    对于操作五,线段树上二分即可

    对于操作六,可以发现 $ log(a imes b)=log a+log b $,所以转化成 $ log x $ 比较和即可

    对于操作七,查询整个线段树点的个数即可

    于是这又是一道大力题

    代码

      1 #include<bits/stdc++.h>
      2 #define LL long long
      3 #define db double
      4 #define _(d) while(d(isdigit(ch=getchar())))
      5 using namespace std;
      6 int R(){
      7     int x;bool f=1;char ch;_(!)if(ch=='-')f=0;x=ch^48;
      8     _()x=(x<<3)+(x<<1)+(ch^48);return f?x:-x;}
      9 const int N=2e6+5;
     10 int n,m,tmp,cnt,fa[N],d[N],rot[N];
     11 struct node{int op,x,y;}q[N];
     12 struct seg{int ls,rs,num;bool tag;db val;}tr[N*20];
     13 int ef(int x){return lower_bound(d+1,d+1+n,x)-d;}
     14 int find(int x){return fa[x]==x?x:fa[x]=find(fa[x]);}
     15 #define Ls(x) tr[x].ls
     16 #define Rs(x) tr[x].rs
     17 void pushup(int rt){
     18     tr[rt].num=tr[Ls(rt)].num+tr[Rs(rt)].num;
     19     tr[rt].val=tr[Ls(rt)].val+tr[Rs(rt)].val;
     20     return;
     21 }
     22 void pushdown(int rt){
     23     tr[rt].tag=0;
     24     tr[Ls(rt)].num=tr[Ls(rt)].val=0,tr[Ls(rt)].tag=1;
     25     tr[Rs(rt)].num=tr[Rs(rt)].val=0,tr[Rs(rt)].tag=1;
     26     return;
     27 }
     28 void insert(int &rt,int l,int r,int k,int x,db y){
     29     if(!rt)rt=++cnt;
     30     if(l==r){tr[rt].num+=x,tr[rt].val+=y;return;}
     31     int mid=(l+r)>>1;
     32     if(tr[rt].tag)pushdown(rt);
     33     if(k<=mid)insert(Ls(rt),l,mid,k,x,y);
     34     else insert(Rs(rt),mid+1,r,k,x,y);
     35     pushup(rt);
     36     return;
     37 }
     38 void merge(int &o1,int o2,int l,int r){
     39     if(!o1||!o2){o1+=o2;return;}
     40     if(l==r){
     41         tr[o1].num+=tr[o2].num,tr[o1].val+=tr[o2].val;
     42         return;
     43     }
     44     int mid=(l+r)>>1;
     45     if(tr[o1].tag)pushdown(o1);
     46     if(tr[o2].tag)pushdown(o2);
     47     merge(Ls(o1),Ls(o2),l,mid),merge(Rs(o1),Rs(o2),mid+1,r);
     48     pushup(o1);
     49     return;
     50 }
     51 int query(int rt,int l,int r,int ql,int qr){
     52     if(!rt||qr<ql)return 0;
     53     if(ql<=l&&qr>=r)return tr[rt].num;
     54     int mid=(l+r)>>1,res=0;
     55     if(tr[rt].tag)pushdown(rt);
     56     if(ql<=mid)res=query(Ls(rt),l,mid,ql,qr);
     57     if(qr>mid)res+=query(Rs(rt),mid+1,r,ql,qr);
     58     return res;
     59 }
     60 void clean(int rt,int l,int r,int ql,int qr){
     61     if(!rt||qr<ql)return;
     62     if(ql<=l&&qr>=r){
     63         tr[rt].num=tr[rt].val=0,tr[rt].tag=1;
     64         return;
     65     }
     66     int mid=(l+r)>>1;
     67     if(ql<=mid)clean(Ls(rt),l,mid,ql,qr);
     68     if(qr>mid)clean(Rs(rt),mid+1,r,ql,qr);
     69     pushup(rt);
     70     return;
     71 }
     72 int ask(int rt,int l,int r,int k){
     73     if(l==r)return d[l];
     74     int mid=(l+r)>>1;
     75     if(tr[rt].tag)pushdown(rt);
     76     if(k<=tr[Ls(rt)].num)return ask(Ls(rt),l,mid,k);
     77     else return ask(Rs(rt),mid+1,r,k-tr[Ls(rt)].num);
     78 }
     79 int main(){
     80     m=R();
     81     for(int i=1;i<=m;i++){
     82         int op=R(),x=R(),y=0;
     83         if(op!=1&&op!=7)y=R();
     84         q[i]=(node){op,x,y};
     85         if(op==3||op==4)d[++n]=y;
     86         if(op==1)d[++n]=x;
     87     }
     88     sort(d+1,d+1+n);
     89     n=unique(d+1,d+1+n)-d-1;
     90     for(int i=1;i<=m;i++){
     91         int op=q[i].op,x=q[i].x,y=q[i].y;
     92         if(op==1)insert(rot[++tmp],1,n,ef(x),1,(db)log(x)),fa[tmp]=tmp;
     93         if(op==2){
     94             int fx=find(x),fy=find(y);
     95             if(fx!=fy)fa[fy]=fx,merge(rot[fx],rot[fy],1,n);
     96         }
     97         if(op==3){
     98             int fx=find(x),k=ef(y),sum=query(rot[fx],1,n,1,k-1);
     99             clean(rot[fx],1,n,1,k-1),insert(rot[fx],1,n,k,sum,sum*log(y));
    100         }
    101         if(op==4){
    102             int fx=find(x),k=ef(y),sum=query(rot[fx],1,n,k+1,n);
    103             clean(rot[fx],1,n,k+1,n),insert(rot[fx],1,n,k,sum,sum*log(y));
    104         }
    105         if(op==5)printf("%d
    ",ask(rot[find(x)],1,n,y));
    106         if(op==6)puts(tr[rot[find(x)]].val>tr[rot[find(y)]].val?"1":"0");
    107         if(op==7)printf("%d
    ",tr[rot[find(x)]].num);
    108     }
    109     return 0;
    110 }
    View Code
  • 相关阅读:
    正确添加Google Adsense
    微软开发主管临别诤言
    DZ论坛重建管理员
    Cook book 第4天 第6章 层、自定义组件
    Cook Book 第二天 运行环境识别修改
    flex cookbook 学习第一天 基本知识
    C#:String类型中的CharAt
    对我学C#时的一次小回忆[一:语法篇]
    分享一段C#反射代码[Type是反射的入口][查看类型信息][动态生成对象]
    C#反射:让私有成员无所遁形
  • 原文地址:https://www.cnblogs.com/chmwt/p/10661727.html
Copyright © 2011-2022 走看看