首页 > 代码库 > Ice-cream Tycoon9(线段树)

Ice-cream Tycoon9(线段树)

线段树的一些基本应用,就是函数写了很多,有点繁琐。

以每个物品的单价建树,刚开始写了个裸的想水过去直接MLE了,然后又离散化了下。

离散化单价后建树,lz数组用来清零,s数组保存结点所含物品个数,co数组保存结点所含物品的所有花费,以找第k大的方式找到第n个物品所在的结点位置i,求出前i-1个结点所包含的物品数量m以及花费ts,那么这n个物品的总花费就为sum = ts+(n-m)*pri[i]  pri表示i离散前的价格,sum与给出的t进行比较得出答案。若可以卖出,则把1--(i-1)清零,把i位置数量减少n-m。

不小心把t也放去离散化了,re 了两次。。

  1 #include <iostream>
  2 #include<cstdio>
  3 #include<cstring>
  4 #include<algorithm>
  5 #include<stdlib.h>
  6 #include<vector>
  7 #include<cmath>
  8 #include<queue>
  9 #include<set>
 10 using namespace std;
 11 #define N 100010
 12 #define LL __int64
 13 #define INF 0xfffffff
 14 const double eps = 1e-8;
 15 const double pi = acos(-1.0);
 16 const double inf = ~0u>>2;
 17 LL s[N<<2],lz[N<<2],co[N<<2];
 18 int po[N*10],a[N],pp[N];
 19 struct node
 20 {
 21     int x;
 22     LL y;
 23     char s[10];
 24 }p[N];
 25 void up(int w)
 26 {
 27     s[w] = s[w<<1]+s[w<<1|1];
 28     co[w] = co[w<<1]+co[w<<1|1];
 29 }
 30 void down(int w,int m)
 31 {
 32     if(lz[w]!=-1)
 33     {
 34         lz[w<<1] = lz[w<<1|1] = lz[w];
 35         s[w<<1] = co[w<<1] = 0;
 36         s[w<<1|1] = co[w<<1|1] = 0;
 37         lz[w] = -1;
 38     }
 39 }
 40 void build(int l,int r,int w)
 41 {
 42     lz[w] = -1;
 43     if(l==r)
 44     {
 45         s[w] = co[w] = 0;
 46         return ;
 47     }
 48     int m = (l+r)>>1;
 49     build(l,m,w<<1);
 50     build(m+1,r,w<<1|1);
 51     up(w);
 52 }
 53 void update(int a,int b,int l,int r,int w)
 54 {
 55     if(a<=l&&b>=r)
 56     {
 57         s[w]  = 0;
 58         co[w] = 0;
 59         lz[w] = 0;
 60         return ;
 61     }
 62     down(w,r-l+1);
 63     int m = (l+r)>>1;
 64     if(a<=m)
 65     update(a,b,l,m,w<<1);
 66     if(b>m)
 67     update(a,b,m+1,r,w<<1|1);
 68     up(w);
 69 }
 70 void upset(int p,int d,int l,int r,int w)
 71 {
 72     if(l==r)
 73     {
 74         s[w]+=d;
 75         co[w]+=(LL)d*pp[l];
 76         return ;
 77     }
 78     down(w,r-l+1);
 79     int m = (l+r)>>1;
 80     if(p<=m) upset(p,d,l,m,w<<1);
 81     else upset(p,d,m+1,r,w<<1|1);
 82     up(w);
 83 }
 84 LL query(int a,int b,int l,int r,int w)
 85 {
 86     if(a<=l&&b>=r) return s[w];
 87     int m = (l+r)>>1;
 88     LL res = 0;
 89     down(w,r-l+1);
 90     if(a<=m) res+=query(a,b,l,m,w<<1);
 91     if(b>m) res+=query(a,b,m+1,r,w<<1|1);
 92     return res;
 93 }
 94 LL queryp(int a,int b,int l,int r,int w)
 95 {
 96     if(a<=l&&b>=r) return co[w];
 97     int m = (l+r)>>1;
 98     LL res = 0;
 99     down(w,r-l+1);
100     if(a<=m) res+=queryp(a,b,l,m,w<<1);
101     if(b>m) res+=queryp(a,b,m+1,r,w<<1|1);
102     return res;
103 }
104 int find(int k,int l,int r,int w)
105 {
106     if(l==r)
107     {
108         return l;
109     }
110     down(w,r-l+1);
111     int m = (l+r)>>1;
112     if(k<=s[w<<1])
113     return find(k,l,m,w<<1);
114     else return find(k-s[w<<1],m+1,r,w<<1|1);
115 }
116 int main()
117 {
118     int x,i,j=0;
119     LL y;
120     int g = 0;
121     while(scanf("%s%d%I64d",p[j].s,&p[j].x,&p[j].y)!=EOF)
122     {
123         if(p[j].s[0]==A)
124         a[j] = p[j].y;
125         else a[j] = 0;
126         j++;
127     }
128     sort(a,a+j);
129     //int o = 0;
130     po[a[0]] = ++g;
131     pp[g] = a[0];
132     for(i = 1 ;i < j ; i++)
133     if(a[i]!=a[i-1])
134     {
135         po[a[i]] = ++g;
136         pp[g] = a[i];
137     }
138     build(1,g,1);
139     for(i = 0  ;i < j; i++)
140     {
141         x = p[i].x;
142         if(p[i].s[0]==A)
143         y = po[p[i].y];
144         else y = p[i].y;
145         if(p[i].s[0]==A)
146         {
147             upset(y,x,1,g,1);
148         }
149         else
150         {
151             if(s[1]<x)
152             {
153                 puts("UNHAPPY");
154                 continue;
155             }
156             int k = find(x,1,g,1);
157             LL ts = 0;
158             if(k>1)
159             ts = query(1,k-1,1,g,1);
160             LL tp = 0;
161             if(k>1)
162             tp = queryp(1,k-1,1,g,1);
163             LL sum = tp+(x-ts)*pp[k];
164            // printf("%I64d\n",sum);
165             if(sum<=y)
166             {
167                 puts("HAPPY");
168                 if(k>1)
169                 update(1,k-1,1,g,1);
170                 upset(k,ts-x,1,g,1);
171             }
172             else puts("UNHAPPY");
173         }
174     }
175     return 0;
176 }
View Code