[bzoj4378][POI2015]Logistyka

来源:互联网 发布:淘宝退货地址哪里修改 编辑:程序博客网 时间:2024/05/02 02:28

4378: [POI2015]Logistyka

Time Limit: 20 Sec Memory Limit: 256 MB
Submit: 226 Solved: 118
[Submit][Status][Discuss]
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 8U 1 5U 2 7Z 2 6U 3 1Z 2 6U 2 2Z 2 6Z 2 1

Sample Output

NIETAKNIETAK

对于每一个询问可以分成这样几种情况讨论:
sum表示权值>=s的个数,num表示权值<s的元素的权值和。
①:sum>=c 这种情况肯定是TAK
②:sum<c&&num>=(csum)s这种情况也肯定是TAK
第二种情况为什么是呢?是因为当num>=(csum)s的时候,说明这时候元素的个数肯定<csum所以一定可以。
最后剩下的一种情况就是NIE了。

#include<iostream>#include<cstdio>#include<cstring>#include<algorithm>using namespace std;#define LL long longconst int N=1000010;int n,m,a[N],o[N],b[N];struct Q{int kind,x,y;}q[N];struct S{LL v;int sum;}tr[N<<2];inline int in(){    int x=0;char ch=getchar();    while(ch<'0'||ch>'9') ch=getchar();    while(ch>='0'&&ch<='9') x=x*10+ch-'0',ch=getchar();    return x;}#define mid (l+r)/2#define L k<<1,l,mid#define R k<<1|1,mid+1,rinline S update(S x,S y){    S ans;    ans.sum=x.sum+y.sum;    ans.v=x.v+y.v;    return ans;}inline void insert(int k,int l,int r,int x,int kind){    if(l==r){        tr[k].v+=(LL)o[l]*kind;        tr[k].sum+=kind;        return ;    }    if(x<=mid) insert(L,x,kind);    else insert(R,x,kind);    tr[k]=update(tr[k<<1],tr[k<<1|1]);}inline S query(int k,int l,int r,int x,int y){    if(y<x) return (S){0,0};    S ans1,ans2;    bool f1=false,f2=false;    if(x<=l&&y>=r) return tr[k];    if(x<=mid) ans1=query(L,x,y),f1=true;    if(y>mid) ans2=query(R,x,y),f2=true;    if(f1&&f2) return update(ans1,ans2);    else return f1?ans1:ans2;}int main(){    int i,x,y;    n=in();m=in();    for(i=1;i<=m;++i){        char ch=getchar();        while(ch!='U'&&ch!='Z') ch=getchar();        if(ch=='U') q[i].kind=1;        if(ch=='Z') q[i].kind=2;        q[i].x=in();q[i].y=in();        a[i]=q[i].y;    }    sort(a+1,a+m+1);    int size=unique(a+1,a+m+1)-a-1;    for(i=1;i<=m;++i){        int now=q[i].y;        q[i].y=lower_bound(a+1,a+size+1,q[i].y)-a;        o[q[i].y]=now;    }    for(i=1;i<=m;++i){        x=q[i].x;y=q[i].y;        if(q[i].kind==1){            if(b[x]) insert(1,1,size,b[x],-1);            b[x]=y; insert(1,1,size,b[x],1);        }        if(q[i].kind==2){            S now=query(1,1,size,y,size);            if(now.sum>=x){                puts("TAK");                continue;            }            int remain=x-now.sum,flag=0;            now=query(1,1,size,1,y-1);            if(now.v>=(LL)remain*(LL)o[y]) flag=1;            if(flag) puts("TAK");            else puts("NIE");         }    }}
1 0
原创粉丝点击