您的位置:首页 > 其它

SGU 311 Ice-cream Tycoon(线段树)

2013-02-26 21:00 267 查看
题目链接:http://acm.sgu.ru/problem.php?contest=0&problem=311

题意:一个商店,有两种操作:(1)ARRIVE n c表示进货n个,每个c元。(2)BUY n t表示一个买货的人要买n个,一共拿了t元钱。如果现在店里的货的数量大于等于n且最便宜的n个的价格小于等于t则将最便宜的卖给他。否则不卖。

思路:线段树的节点保存该段货物的数量和总价格,另外增加一个标志标记该段内是否被卖完。标记每次向下传递。注意在计算最便宜的n个的价格时向下传递标志时要向上更新sum和value值。因为若这次不向上更新,若本次的价格和大于t则不会再进行删掉前n个的操作,就会出错。

const int N=100005;
const int M=300005;

struct query
{
char cmd[10];
i64 n,c;
};

struct node
{
i64 sum,value;
int L,R,mid,flag;
};

query q
;
vector<i64> V;
map<i64,int> Map;
int n,m;
node a[M];

void build(int t,int L,int R)
{
a[t].L=L;
a[t].R=R;
a[t].mid=(L+R)>>1;
a[t].flag=0;
a[t].sum=a[t].value=0;
if(L==R) return;
build(t*2,L,a[t].mid);
build(t*2+1,a[t].mid+1,R);
}

void mark(int u)
{
if(u>M) return;
a[u].flag=1;
a[u].sum=a[u].value=0;
}

void down(int t)
{
if(t>M||!a[t].flag) return;
a[t].flag=0;
mark(t*2);mark(t*2+1);
}

void up(int t)
{
a[t].sum=a[t*2].sum+a[t*2+1].sum;
a[t].value=a[t*2].value+a[t*2+1].value;
}

void insert(int t,int pos,i64 n)
{
down(t);
if(a[t].L==a[t].R)
{
a[t].sum+=n;
a[t].value+=V[pos-1]*n;
return;
}
if(pos<=a[t].mid) insert(t*2,pos,n);
else insert(t*2+1,pos,n);
up(t);
}

i64 get(int t,i64 n)
{
down(t);
if(n==a[t].sum) return a[t].value;
if(a[t].L==a[t].R) return a[t].value/a[t].sum*n;
up(t);
if(n<=a[t*2].sum) return get(t*2,n);
return a[t*2].value+get(t*2+1,n-a[t*2].sum);
}

void del(int t,i64 n)
{
down(t);
if(n==a[t].sum)
{
mark(t);
return;
}
if(a[t].L==a[t].R)
{
a[t].value-=a[t].value/a[t].sum*n;
a[t].sum-=n;
return;
}
if(n<=a[t*2].sum) del(t*2,n);
else
{
del(t*2+1,n-a[t*2].sum);
mark(t*2);
}
up(t);
}

void deal(i64 n,i64 t)
{
if(a[1].sum<n||get(1,n)>t) puts("UNHAPPY");
else puts("HAPPY"),del(1,n);
}

int main()
{
while(scanf("%s%lld%lld",q[n+1].cmd,&q[n+1].n,&q[n+1].c)!=-1)
{
n++;
if(q
.cmd[0]=='A') V.pb(q
.c);
}
sort(V.begin(),V.end());
m=unique(V.begin(),V.end())-V.begin();
int i,k;
FOR0(i,m) Map[V[i]]=i+1;
build(1,1,m);
FOR1(i,n)
{
if(q[i].cmd[0]=='A')
{
k=Map[q[i].c];
insert(1,k,q[i].n);
}
else deal(q[i].n,q[i].c);
}
return 0;
}


  
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: