发现询问是针对整个区间,也就是说位置什么用都没有
发现我们需要构造出(s)个长度为(c)的数列,每个数只能在一个数列中出现一次,且一个数最多的使用次数是其大小
对于那些大于等于(s)的数,我们让这些数在每一个数列里都出现就好了,如果这样的数有(val)个,相当于我们要构造的数列的长度变成了(c-val)
对于小于(s)的数我们可以让这些数在每一个数列里尽量出现,看一下这些数的和是否能充满剩下的(s imes(c-val))个位置就好了
树状数组维护一下就好了
代码
#include<algorithm>
#include<cstdio>
#define LL long long
#define lowbit(i) ((i)&(-i))
#define re register
#define maxn 1000005
inline int read() {
char c=getchar();int x=0;while(c<'0'||c>'9') c=getchar();
while(c>='0'&&c<='9') x=(x<<3)+(x<<1)+c-48,c=getchar();return x;
}
int n,m,sz;
char opt[maxn][2];
int a[maxn],b[maxn],c[maxn],pos[maxn];
struct Bit {
LL t[maxn];
inline void add(int x,int val) {for(re int i=x;i<=sz;i+=lowbit(i)) t[i]+=val;}
inline LL ask(int x) {LL now=0;for(re int i=x;i;i-=lowbit(i)) now+=t[i];return now;}
}B[2];
inline int find(int x) {
int l=1,r=sz;
while(l<=r) {
int mid=l+r>>1;
if(c[mid]==x) return mid;
if(c[mid]>x) r=mid-1;else l=mid+1;
}
return 0;
}
int main() {
n=read(),m=read();
for(re int i=1;i<=m;i++) scanf("%s",opt[i]),a[i]=read(),b[i]=read(),c[i]=b[i];
std::sort(c+1,c+m+1),sz=std::unique(c+1,c+m+1)-c-1;
for(re int i=1;i<=m;i++) {
int x=find(b[i]);
if(opt[i][0]=='U') {
if(pos[a[i]]) B[0].add(pos[a[i]],-1),B[1].add(pos[a[i]],-1*c[pos[a[i]]]);
B[0].add(x,1),B[1].add(x,b[i]);pos[a[i]]=x;
}
else {
a[i]-=B[0].ask(sz)-B[0].ask(x-1);
if(a[i]<=0) {puts("TAK");continue;}
if(B[1].ask(x-1)>=(LL)a[i]*(LL)b[i]) puts("TAK");
else puts("NIE");
}
}
return 0;
}