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

 

你可能感兴趣的:(线段树)