zoukankan      html  css  js  c++  java
  • 积木---------------权值线段树,模拟

    问题描述


    Alien 喜欢玩积木,场地是一横排底座,一开始都没有积木,编号为 1~10^6 。
    若对于任意 l<=k<=r,第k 列上存在积木,且第 l-1 列不存在积木或 l=1,第
    r+1 列不存在积木或 r=10^6 ,则称第 l~r 列为一个塔,
    第 l 列为该塔的第 1 列,该塔的长度为 r-l+1。由于堆积木太累,他新买了一
    个机器人帮他堆积木,机器人有两种操作:
    put x c:表示在第 x 列上增加c 个积木(c>0)。
    tput t x c:表示在塔 t 的第 x 列上增加c 个积木(c>0)。
    由于机器人能搬运的积木太多,一排积木让他眼花缭乱,
    你需要回答四种问题:
    towers:询问共有几座塔。
    cubes t:询问第 t 座塔共有几个积木。
    length t:询问第 t 座塔的长度。
    tcubes t x:询问第 t 座塔的第 x 列有几个积木。
    现给出机器人的所有操作,请回答所有询问。
    数据保证每一列的积木数不超过 int 范围。

    输入

    第一行为总操作和询问的数量 n。下面 n 行表示机器人的操作和 Alien 的询问。【输出】对于每个询问输出一行,具体格式见样例。

    输入样例

    22
    towers
    put 2 5
    put 1 6
    put 3 6
    put 3 3
    towers
    length 1
    put 6 3
    put 5 4
    length 2
    tcubes 2 1
    tcubes 2 2
    towers
    cubes 1
    cubes 2
    put 4 3
    towers
    cubes 1
    tput 1 6 50
    cubes 1
    tcubes 1 6
    length 1

    输出样例

    0 towers
    1 towers
    length of 1th tower is 3
    length of 2th tower is 2
    4 cubes in 1th column of 2th tower
    3 cubes in 2th column of 2th tower
    2 towers
    20 cubes in 1th tower
    7 cubes in 2th tower
    1 towers
    30 cubes in 1th tower
    80 cubes in 1th tower
    53 cubes in 6th column of 1th tower
    length of 1th tower is 6

    数据说明

    对于 10% 的数据 只含操作 put 和询问 tower,
    对于另 20% 的数据 n<=10,
    对于 100% 的数据 0<n<=10^6 ,保证数据合法。


    1. 可以发现该题最主要的操作就是查询第 k 个 tower。

    2. 上述操作用权值线段树维护即可。

    3. 然后就是模拟了。

      1 #include<bits/stdc++.h>
      2 #define ll long long
      3 using namespace std;
      4 int n,z,x,pos;
      5 char opt[10];
      6 ll s[1000050],y;
      7 int len[1000050],fa[1000050];
      8 struct tree
      9 {
     10     int sum[4000050];
     11     void calc_add(int u,int v,int val,int l,int r)
     12     {
     13         sum[u]+=val;
     14         if(l==r)
     15             return ;
     16         int mid=(l+r)>>1;
     17         if(v<=mid)
     18             calc_add(u<<1,v,val,l,mid);
     19         else
     20             calc_add(u<<1|1,v,val,mid+1,r);
     21     }
     22     int calc_ask(int u,int v,int l,int r)
     23     {
     24         if(l==r)
     25             return l;
     26         int mid=(l+r)>>1;
     27         if(v<=sum[u<<1])
     28             return calc_ask(u<<1,v,l,mid);
     29         else
     30             return calc_ask(u<<1|1,v-sum[u<<1],mid+1,r);
     31     }
     32 }tow;
     33 struct szsz
     34 {
     35     ll c[1000050];
     36     void calc_add(int u,ll v)
     37     {
     38         while(u<=1e6)
     39         {
     40             c[u]+=v;
     41             u+=u&-u;
     42         }
     43     }
     44     ll calc_ask(int u)
     45     {
     46         ll sum=0;
     47         while(u)
     48         {
     49             sum+=c[u];
     50             u-=u&-u;
     51         }
     52         return sum;
     53     }
     54 }val;
     55 int find(int u)
     56 {
     57     return fa[u]==u? u:fa[u]=find(fa[u]);
     58 }
     59 int main()
     60 {
     61     for(int i=1;i<=1e6;++i)
     62         fa[i]=i;
     63     scanf("%d",&n);
     64     while(n--)
     65     {
     66         scanf(" %s",opt);
     67         if(opt[0]=='p')
     68         {
     69             scanf("%d%lld",&x,&y);
     70             s[x]+=y;
     71             val.calc_add(x,y);
     72             if(s[x]==y)
     73             {
     74                 if(s[x-1]==0&&s[x+1]==0)
     75                 {
     76                     tow.calc_add(1,x,1,1,1e6);
     77                     len[x]=1;
     78                 }
     79                 else if(s[x-1]&&!s[x+1])
     80                 {
     81                     ++len[find(x-1)];
     82                     fa[x]=fa[x-1];
     83                 }
     84                 else if(s[x+1]&&!s[x-1])
     85                 {
     86                     len[x]=len[x+1]+1;
     87                     len[x+1]=0;
     88                     fa[x+1]=x;
     89                     tow.calc_add(1,x+1,-1,1,1e6);
     90                     tow.calc_add(1,x,1,1,1e6);
     91                 }
     92                 else
     93                 {
     94                     pos=find(x-1);
     95                     fa[x+1]=pos;
     96                     len[pos]+=len[x+1]+1;
     97                     len[x+1]=0;
     98                     tow.calc_add(1,x+1,-1,1,1e6);
     99                 }
    100             }
    101         }
    102         else if(opt[1]=='p')
    103         {
    104             scanf("%d%d%lld",&z,&x,&y);
    105             pos=tow.calc_ask(1,z,1,1e6)+x-1;
    106             val.calc_add(pos,y);
    107             s[pos]+=y;
    108         }
    109         else if(opt[1]=='o')
    110         {
    111             printf("%d towers
    ",tow.sum[1]);
    112         }
    113         else if(opt[1]=='u')
    114         {
    115             scanf("%d",&z);
    116             pos=tow.calc_ask(1,z,1,1e6);
    117             printf("%lld cubes in %dth tower
    ",val.calc_ask(pos+len[pos]-1)-val.calc_ask(pos-1),z);
    118         }
    119         else if(opt[1]=='e')
    120         {
    121             scanf("%d",&z);
    122             pos=tow.calc_ask(1,z,1,1e6);
    123             printf("length of %dth tower is %d
    ",z,len[pos]);
    124         }
    125         else if(opt[1]=='c')
    126         {
    127             scanf("%d%d",&z,&x);
    128             pos=tow.calc_ask(1,z,1,1e6);
    129             printf("%lld cubes in %dth column of %dth tower
    ",s[pos+x-1],x,z);
    130         }
    131     }
    132     return 0;
    133 }
    代码
  • 相关阅读:
    50个网页常用小代码
    web前端题目(持续更新)
    一步步构建大型网站架构(转)
    CentOS下配置node.js
    ajax文件上传
    test
    文件上传input简便美化方案
    String.match()与RegExp.exec()
    ie7下zindex问题
    javascript将数组插入到另一个数组中
  • 原文地址:https://www.cnblogs.com/wyher/p/9850265.html
Copyright © 2011-2022 走看看