求卡常
查看原帖
求卡常
857323
linxuanrui楼主2025/1/27 11:46

我写的是 O(nlog2n)O(n\log^2n) 的大常数树套树做法,有没有好心人帮忙卡常。

#include<bits/stdc++.h>
#define endl '\n'
typedef long long ll;
using namespace std;
namespace fastIO{
    #define f_inline inline __attribute__((always_inline))
    char buf[1048576],*p1 = buf,*p2 = buf;
    f_inline char gc(){return (p1 == p2 && (p2 = (p1 = buf) + fread(buf,1,1048576,stdin),p1 == p2) ? EOF : *p1++);}
    f_inline int read(){//读入一个数字 
        int x = 0;char ch = gc();
        while(!isdigit(ch))ch = gc();
        while(isdigit(ch)){x = x * 10 + (ch ^ 48),ch = gc();}
        return x; 
    }
    char buffer[800000];int _p1 = -1;
    #define pc(x) buffer[++_p1] = x
};
using namespace fastIO;
const int N = 2e5 + 5;
int n,q,opt,l[N],r[N],cnt,CNT,x,ans;
map<pair<int,int>,int> mp;
unsigned root[N];
struct node{
	unsigned ls,rs,sum,tag;
}tree[N * 60];
void update(unsigned &p,int L,int R,int l,int r,int x){
	if(!p)p = ++CNT;
//	cout << p << " " << L << " " << R << " " << l << " " << r << " " <<x << endl;
	if(l <= L && R <= r)return tree[p].sum += x,tree[p].tag += x,void();
	int mid = (L + R) >> 1;
	if(tree[p].tag){
		int ls = tree[p].ls,rs = tree[p].rs;
		if(ls)tree[ls].sum += tree[p].tag,tree[ls].tag += tree[p].tag;
		if(rs)tree[rs].sum += tree[p].tag,tree[rs].tag += tree[p].tag;
		tree[p].tag = 0;
	}
	if(l <= mid)update(tree[p].ls,L,mid,l,r,x);
	if(mid < r)update(tree[p].rs,mid + 1,R,l,r,x);
	tree[p].sum = tree[tree[p].ls].sum + tree[tree[p].rs].sum;
}
int query(unsigned p,int L,int R,int l,int r){
	if(l <= L && R <= r)return tree[p].sum;
	if(tree[p].tag){
		int ls = tree[p].ls,rs = tree[p].rs;
		if(ls)tree[ls].sum += tree[p].tag,tree[ls].tag += tree[p].tag;
		if(rs)tree[rs].sum += tree[p].tag,tree[rs].tag += tree[p].tag;
		tree[p].tag = 0;
	}
	int mid = (L + R) >> 1,ans = 0;
	if(l <= mid && tree[tree[p].ls].sum)ans += query(tree[p].ls,L,mid,l,r);
	if(mid < r && tree[tree[p].rs].sum)ans += query(tree[p].rs,mid + 1,R,l,r);
	return ans;
}
#define lowbit(x) ((x) & (-x))
void update(int l,int r,int x){
	for(int i = r;i <= n;i += lowbit(i))update(root[i],1,n,l,l,x);
}
int query(int l,int r){// 包含在 [l,r] 
	int ans = 0;
	for(int i = r;i >= 1;i -= lowbit(i))ans += query(root[i],1,n,l,r);
	return ans;
}
int query2(int l,int r){// l' <= l,r' <= r
	int ans = 0;
	for(int i = r;i >= 1;i -= lowbit(i))ans += query(root[i],1,n,1,l);
	return ans;
}
struct BIT{
	int tree[N];
	void update(int pos,int x){for(int i = pos;i <= n;i += lowbit(i))tree[i] += x;}
	int query(int pos){int ans = 0;for(int i = pos;i >= 1;i -= lowbit(i))ans += tree[i];return ans;}
}t1,t2;
signed main(){
//	ios::sync_with_stdio(false);
//	cin.tie(0);
//	cout.tie(0);
	n = read(),q = read();
//	cin >> n >> q;
	for(int i = 1;i <= q;i++){
//		cin >> opt
		opt = read();
		if(opt == 1){
			l[i] = read(),r[i] = read();
//			cin >> l[i] >> r[i];
			ans += -t1.query(l[i] - 1) + t2.query(r[i]) - query(l[i],r[i]) - t2.query(l[i]) + query2(l[i],r[i] - 1) + mp[{l[i],r[i]}];
			update(l[i],r[i],1);
			t1.update(r[i],1),t2.update(l[i],1);
			mp[{l[i],r[i]}]++;
		}
		else{
			x = read();
//			cin >> x;
			update(l[x],r[x],-1);
			t1.update(r[x],-1),t2.update(l[x],-1);
			mp[{l[x],r[x]}]--;
			ans -= -t1.query(l[x] - 1) + t2.query(r[x]) - query(l[x],r[x]) - t2.query(l[x]) + query2(l[x],r[x] - 1) + mp[{l[x],r[x]}];
//			cout << query(l[x],r[x]) << endl;
		}
//		cout << ans << " ";
//		cout << "NO\n";
		if(ans)pc('N'),pc('o');
		else pc('Y'),pc('e'),pc('s');
		pc('\n');
	}
	fwrite(buffer,1,_p1 + 1,stdout);
}
2025/1/27 11:46
加载中...