积木---------------权值线段树,模拟

问题描述


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\n",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\n",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\n",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\n",s[pos+x-1],x,z);
130         }
131     }
132     return 0;
133 }
代码

 

posted @ 2018-10-25 15:41  Hevix  阅读(219)  评论(0编辑  收藏  举报