【POI2015】【BZOJ4378】Logistyka

Description

维护一个长度为n的序列,一开始都是0,支持以下两种操作:
1.U k a 将序列中第k个数修改为a。
2.Z c s 在这个序列上,每次选出c个正数,并将它们都减去1,询问能否进行s次操作。
每次询问独立,即每次询问不会对序列进行修改。

Input

第一行包含两个正整数n,m(1<=n,m<=1000000),分别表示序列长度和操作次数。
接下来m行为m个操作,其中1<=k,c<=n,0<=a<=10^9,1<=s<=10^9。

Output

包含若干行,对于每个Z询问,若可行,输出TAK,否则输出NIE。

Sample Input

3 8

U 1 5

U 2 7

Z 2 6

U 3 1

Z 2 6

U 2 2

Z 2 6

Z 2 1
Sample Output

NIE

TAK

NIE

TAK
HINT

鸣谢Claris

Source

鸣谢Claris

考虑建两个树状数组,都是权值BIT
一个记录出现次数一个前缀和
这样来思考:选数时候为了能选出s次,肯定尽量从大的里选
然后乱搞一下..
考虑把这些数分为大于等于s和小于s
大于等于s的最多只要取s次就好了,小于s的直接求和

需要离散化

BZOJ RE又显示成WA..一直调不出来..简直了..

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#define lowbit(x)   (x&(-x))
#define GET (ch>='0'&&ch<='9')
#define MAXN 1000010
#define LL long long
using namespace std;
int n,m;
int a[MAXN],v[MAXN],cnt;
char ch[2];
struct BIT
{
    LL c[MAXN];
    inline void add(int x,int delta)
    {
        if (!x) return;
        for (int i=x;i<=cnt;i+=lowbit(i))   c[i]+=delta;
    }
    inline LL query(int x)
    {
        LL ret=0;
        for (int i=x;i;i-=lowbit(i))    ret+=c[i];
        return ret;
    }
}s[3];
void in(int &x)
{
    char ch=getchar();x=0;
    while (!GET)    ch=getchar();
    while (GET) x=x*10+ch-'0',ch=getchar();
}
struct Query
{
    int opt,x,y;
}q[MAXN];
int main()
{
    in(n);in(m);int x,y;
    for (int i=1;i<=m;i++)
    {
        scanf("%s",ch);in(x);in(y);v[i]=y;
        q[i].opt=(ch[0]=='U');q[i].x=x;q[i].y=y;
    }
    sort(v+1,v+m+2);cnt=unique(v+1,v+m+2)-(v+1);
    for (int i=1;i<=m;i++)  q[i].y=lower_bound(v+1,v+cnt+1,q[i].y)-v;
    for (int i=1;i<=m;i++)
        if (q[i].opt)
        {
            x=a[q[i].x];s[1].add(x,-1);s[2].add(x,-v[x]);
            x=a[q[i].x]=q[i].y;
            s[1].add(x,1);s[2].add(x,v[x]);
        }
        else
        {
            if (s[2].query(q[i].y-1)+(s[1].query(cnt)-s[1].query(q[i].y-1))*v[q[i].y]>=(LL)q[i].x*v[q[i].y])    puts("TAK");
            else    puts("NIE");
        }
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值