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 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
对于每一个询问可以分成这样几种情况讨论:
用
sum
表示权值
>=s
的个数,
num
表示权值
<s
<script type="math/tex" id="MathJax-Element-722">
①:
sum>=c
这种情况肯定是
TAK
。
②:
sum<c
&&
num>=(c−sum)∗s
这种情况也肯定是
TAK
。
第二种情况为什么是呢?是因为当
num>=(c−sum)∗s
的时候,说明这时候元素的个数肯定
<c−sum
<script type="math/tex" id="MathJax-Element-729">
最后剩下的一种情况就是
NIE
了。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
#define LL long long
const 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,r
inline 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");
}
}
}