80分求条,马蜂还算良好
查看原帖
80分求条,马蜂还算良好
706209
[丘李]Chilllee楼主2024/12/3 17:59
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn = 1e6 + 10;
int n, m;
int op[maxn];
int oa[maxn], ob[maxn];
int a[maxn]; // 原序列
int num[maxn];
ll sum[maxn];
int zero_num;
int dis[maxn], dcnt, cnt; // discretization
map<int, int > mp;

inline long long read(){
	char readch=getchar(); ll readtmp=0;
	ll readflag=1;
	while(readch<'0' || '9'<readch){if(readch=='-')readflag=-1;readch=getchar();}
	while('0'<=readch && readch<='9'){readtmp=readtmp*10+readch-'0';readch=getchar();}
	return readtmp*readflag;
}

void pre(){
	cin >> n >> m;
	zero_num = n;// 最开始全是0
	
	for(int i=1; i<=m; i++){
		char ch ;
		scanf(" %c", &ch);
		oa[i] = read();
		ob[i] = read();
		
		dis[++dcnt] = ob[i];
		

		if(ch == 'U') op[i] = 1;
		else op[i] = 2;
	}
	sort(dis+1, dis+1+dcnt);
	
	for(int i=1; i<=dcnt; i++){
		if(dis[i-1] == dis[i]) continue;//此时也避免了0的加入
		else {++cnt; mp[dis[i]] = cnt; dis[cnt] = dis[i];}
	}
	
	
}

// 建立两个树状数组,一个用于存每个位置有多少个数
// 另一个用于记录前缀和
// 每次查询,先记录 >=s 的数字的个数,再找 < s 的所有数求和是否能够凑出剩下的所有要求
// O(nlog)

void insert(int x, int y){
	for(; x <= cnt; x += x & (-x)) num[x] += y;
}
// cnt 是离散化后数量

int find(int s){
	int res = 0;
	for(; s; s -= s & (-s)) res += num[s]; 
	return res;
}
///

void add(int x, int y){
	for(; x <= cnt ; x += x & (-x)) sum[x] += y;
}


ll query(int s){
	ll res = 0;
	for(; s; s -= s & (-s)) res += sum[s];
	return res;
}


int main(){
	freopen("1.in", "r", stdin);
	
	pre();

	for(int i=1; i<=m; i++){
		if(op[i] == 1){
			int origin = a[oa[i]];
			a[oa[i]] = ob[i];
			if(origin) insert(origin, -1);
			if(ob[i]) insert(mp[ob[i]], 1);
			if(origin) add(mp[origin], -origin);
			if(ob[i]) add(mp[ob[i]], ob[i]);
			if(origin == 0 && ob[i]) zero_num--;
			else if(origin && ob[i] == 0) zero_num++;
		}
		else {
			int number = n - find(mp[ob[i]] - 1) - zero_num;
			//printf("number: %d, mo[ob[i]]: %d \n", number, mp[ob[i]]);
			if(oa[i] <= number){
				printf("TAK\n");
				continue;
			}
			ll tmp =  max(oa[i] - number, 0); tmp *= ob[i];
			int id = lower_bound(dis+1, dis+1+cnt, ob[i]) - dis;
			
			ll b = query(id-1);
			//printf("id: %d; b: %d; tmp: %d\n", id, b, tmp);
			if(b >= tmp) printf("TAK\n");
			else printf("NIE\n");
		}
	}


	return 0;
}
2024/12/3 17:59
加载中...