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 了两次。。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
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 }