不闪躲 将深红唇色涂抹 让白瞳浸染烈火 感受心灵的赤裸 打开锁

test2

t4 能写那么多行真是头祝。t4 能写那么多行真是头祝。t4 能写那么多行真是头祝。t4 能写那么多行真是头祝。t4 能写那么多行真是头祝。t4 能写那么多行真是头祝。t4 能写那么多行真是头祝。


买礼物gift

枚举最大值贪心即可。

#include<bits/stdc++.h>
#define int long long
#define up(i,l,r) for(int i=l; i<=r; ++i)
#define dn(i,r,l) for(int i=r; i>=l; --i)

using namespace std;

const int N=200005;

int T, n, suf[N], Ans, sp[N];
struct node {
	int a, b;
	bool operator<(const node &rhs) const {	return a<rhs.a; }
} p[N];

void mian() {
	cin >> n, Ans=1e13;
	up(i,1,n) cin >> p[i].a >> p[i].b;
	sort(p+1,p+1+n);
	suf[n+1]=-1e13;
	dn(i,n,1) suf[i]=max(suf[i+1],p[i].b); 
	up(i,1,n) sp[i]=p[i].b;
	sort(sp+1,sp+1+n);
	map<int,int> tag;
	up(i,1,n) {
		Ans=min(Ans,abs(p[i].a-suf[i+1]));
		int l=upper_bound(sp+1,sp+1+n,p[i].a)-sp-1;
		int r=lower_bound(sp+1,sp+1+n,p[i].a)-sp;
		l=sp[l], r=sp[r];
		if(tag[l]&&l>suf[i+1]) Ans=min(Ans,abs(p[i].a-l));
		if(tag[r]&&r>suf[i+1]) Ans=min(Ans,abs(p[i].a-r));
		tag[p[i].b]=1;
//		cout << i << " " << p[i].a << ' ' << suf[i+1] << ' ' << l << ' ' << r << '\n';
	}
	cout << Ans << '\n';
}

signed main() {
	freopen("gift.in","r",stdin);
	freopen("gift.out","w",stdout);
	ios::sync_with_stdio(0);
	cin.tie(0);
	cin >> T;
	while(T--) mian();
	return 0;
}

追忆recall

要求约分后分母为 \(2^p5^q\),不妨先枚举 \(p,q\)。分数形如 \(\frac{yx}{(2^p5^q)x}\),对因数有要求,枚举一个另一个的方案数可以小容斥+整除分块计算。

#include<bits/stdc++.h>
#define int long long
#define up(i,l,r) for(int i=l; i<=r; ++i)
#define dn(i,r,l) for(int i=r; i>=l; --i)
#define pb push_back

using namespace std;

const int N=2000005;

int n, s[N], lr[N], tot, Ans;

int check(int p,int q) {
	int mul=1;
	while(p--) {
		if(2*mul>n) return -1;
		mul*=2;
	}
	while(q--) {
		if(5*mul>n) return -1;
		mul*=5;
	}
	return mul;
}

void mat(int op) {
	int x=n/op, sum=0;
	for(int l=1, r; l<=x; l=r+1) {
		if(x/l) r=min(x,x/(x/l)); else r=x;
		++tot, s[tot]=sum, lr[tot]=l;
		sum+=(r-l+1)*(x/l);
	}
//	cout << "wq " << tot << '\n';
}

int sum(int op,int x) {
	x=n/op/x;
	if(x<1||!tot) return 0;
	int l=1, r=tot, p;
	while(l<=r) {
		int mid=(l+r)>>1;
		if(lr[mid]<=x) p=mid, l=mid+1;
		else r=mid-1;
	}
	return s[p]+n/op/lr[p]*(x-lr[p]+1);
}

signed main() {
	freopen("recall.in","r",stdin);
	freopen("recall.out","w",stdout);
	ios::sync_with_stdio(0);
	cin.tie(0);
	cin >> n;
	mat(1);
	up(p,0,100) up(q,0,100) {
		int mul=check(p,q);
		if(mul<0) continue;
		Ans+=sum(1,mul);
	} tot=0;
	mat(2);
	up(p,0,100) up(q,0,100) {
		int mul=check(p,q);
		if(mul<0) continue;
		Ans-=sum(2,mul);
	} tot=0;
	mat(5);
	up(p,0,100) up(q,0,100) {
		int mul=check(p,q);
		if(mul<0) continue;
		Ans-=sum(5,mul);
	} tot=0;
	mat(10);
	up(p,0,100) up(q,0,100) {
		int mul=check(p,q);
		if(mul<0) continue;
		Ans+=sum(10,mul);
	} tot=0;
	cout << Ans;
	return 0;
}

状元桥run

首先去重的 \(n'\) 级别是假的,因为显然至少要 \(\frac{(1+n)n}{2}\) 这么多的时间,所以位置种类只有不超过 \(O(L)\) 种。

然后可以观察到第一个拿的一定是 \(1/n\),理由是一个点一定在最后一次经过的时候拿,因为这个某一个时刻拿的球一定是一个前缀拼后缀,dp 求出最好情况即可。

#include<bits/stdc++.h>
#define int long long
#define up(i,l,r) for(int i=l; i<=r; ++i)
#define dn(i,r,l) for(int i=r; i>=l; --i)
#define pb push_back

using namespace std;

const int N=500005, M=1005;

int n, m, l, v[N], c[N], init[N], q, f[2][M][M][2], sl[N], sr[N];

inline void chk(int &a,int b) { a=min(a,b); }

signed main() {
//	freopen("1.txt","r",stdin); 
	freopen("run.in","r",stdin);
	freopen("run.out","w",stdout);
	ios::sync_with_stdio(0);
	cin.tie(0);
	cin >> n >> l;
	up(i,1,n) cin >> q, ++init[q];
	up(i,0,l) if(init[i]) ++m, v[m]=i, c[m]=init[i];
	up(i,1,m) sl[i]=sl[i-1]+c[i];
	dn(i,m,1) sr[i]=sr[i+1]+c[i];
	cin >> q;
	if((1+m)*m/2>=5e5) {
		while(q--) cout << "No\n";
		return 0;
	}
	memset(f,0x3f,sizeof(f));
	f[0][1][m+1][0]=f[1][0][m][1]=0; 
	up(i,1,m-1) {
		up(l,0,i) {
			int r=m+1-i+l;
//			f[l][r] -> f[l+1][r]
			chk(f[0][l+1][r][0],f[0][l][r][0]+abs(v[l]-v[l+1])*(sl[l]+sr[r]+1));
			chk(f[0][l+1][r][0],f[0][l][r][1]+abs(v[r]-v[l+1])*(sl[l]+sr[r]+1)); 
			chk(f[0][l][r-1][1],f[0][l][r][0]+abs(v[l]-v[r-1])*(sl[l]+sr[r]+1));
			chk(f[0][l][r-1][1],f[0][l][r][1]+abs(v[r]-v[r-1])*(sl[l]+sr[r]+1));
//			f[l][r] -> f[l][r-1]
			chk(f[1][l+1][r][0],f[1][l][r][0]+abs(v[l]-v[l+1])*(sl[l]+sr[r]+1));
			chk(f[1][l+1][r][0],f[1][l][r][1]+abs(v[r]-v[l+1])*(sl[l]+sr[r]+1)); 
			chk(f[1][l][r-1][1],f[1][l][r][0]+abs(v[l]-v[r-1])*(sl[l]+sr[r]+1));
			chk(f[1][l][r-1][1],f[1][l][r][1]+abs(v[r]-v[r-1])*(sl[l]+sr[r]+1));
		}
	}
	while(q--) {
		int s, t, lim, Ans=1e13;
		cin >> s >> t >> lim;
		int pre=upper_bound(v+1,v+1+m,t)-v-1, nxt=lower_bound(v+1,v+1+m,t)-v;
		if(!pre) ++pre;
		chk(Ans,abs(s-v[1])+f[0][pre][pre+1][0]+abs(t-v[pre])*(n+1));
		chk(Ans,abs(s-v[1])+f[0][nxt-1][nxt][1]+abs(t-v[nxt])*(n+1));
		chk(Ans,abs(s-v[m])+f[1][pre][pre+1][0]+abs(t-v[pre])*(n+1));
		chk(Ans,abs(s-v[m])+f[1][nxt-1][nxt][1]+abs(t-v[nxt])*(n+1));
		if(Ans+n<=lim) cout << "Yes\n"; else cout << "No\n";
	}
	return 0;
}

舞会party

先不管区间限制考虑问题。\(i\) 可以送礼物给 \(a_i>b_j\)\(j\),要求 \(i\) 恰好出入度为 \(1\),显然是一个考虑是否存在完美匹配的问题,等价于求 \(|S|> |N(S)|\) 是否恒成立。

考虑一个集合 \(S\) 是否满足 \(|S|> |N(S)|\),又 \(a_i>b_i\) 不难发现满足仅有 \(S\)\(a\) 的最大/次大值为 \(a_r/a_l\) 满足 \(a_l<b_r<a_l\) 且不存在 \(i(\neq S)\) 满足 \(b_i<a_i\)

我们希望知道有没有 \(S\) 满足 \(|S|> |N(S)|\)(下称漂亮),不妨考虑 \(a_r\) 作为最大 \(a\) 是否能找出不合法 \(S\),所以考虑 \(i(\neq r)\) 是否放到 \(S\) 里面。

  • 如果 \(a_i>a_r\),只能放到 \(S\) 外面,应该有 \(b_i>a_r\)。综合下来就是只用满足 \(b_i>a_r\) 就不会影响漂亮性。

  • 如果 \(a_i<a_r\),如果放到 \(S\) 外面的话一定满足 \(b_i<a_r\) 一定会导致不漂亮,必须放到 \(S\) 里面,要求 \(a_i<b_r\)。综合下来就是只要满足 \(a_i<b_r\) 就不会影响漂亮性。

题目希望对于每一个 \(a_r\) 对应不出来漂亮的 \(S\),也就是存在一个一定影响漂亮性的 \(i\)。又因为题目是区间查询,对于每一个 \(a_r\) 我们只关心左右第一个 \(i\) 满足 \(b_i<a_r\)\(a_i>b_r\)。这个可以 cdq 分治,但是也可以线段树,一维排序一次出现来偏序,令一位在线段树上维护区间最值,然后线段树二分找到位置即可。

对于每一个 \(r\) 希望 \(L_r/R_r\in [Q_l,Q_r]\),只需要查询是否存在 \(L_r<Q_l<r<Q_r<R_r\),二维偏序多来几次就行了。

#include<bits/stdc++.h>
#define int long long
#define up(i,l,r) for(int i=l; i<=r; ++i)
#define dn(i,r,l) for(int i=r; i>=l; --i)
#define ls(p) (p<<1)
#define rs(p) (p<<1|1)
#define pb push_back

using namespace std;

const int N=1000005;

int n, m, tot, ran, a[N], b[N], Ans[N], tr[N<<2], l[N], r[N], bit[N];
struct Query {
	int i, id, v;
	Query() {}
	Query(int I,int Id,int V) { i=I, id=Id, v=V; } 
	bool operator<(const Query &rhs) const { return i<rhs.i; }
} arr[N];
struct node {
	int id, l, r;
	node() {}
	node(int Id,int L,int R) { id=Id, l=L, r=R; }
	bool operator<(const node &rhs) const {
		if(l!=rhs.l) return l>rhs.l;
		return id>rhs.id;
	}
} p[N];
struct hypoxia {
	int id, r, v;
	hypoxia() {}
	hypoxia(int Id,int R,int V) { id=Id, r=R, v=V; }
	bool operator<(const hypoxia rhs) const { return r<rhs.r; } 
} o[N];

void updata(int x,int v,int p=1,int s=1,int e=n) {
//	cout << "upt " << x <<  ' ' << v << " : " << tr[1] << '\n';
	if(s==e) { tr[p]=v; return; }
	int mid=(s+e)>>1;
	if(x<=mid) updata(x,v,ls(p),s,mid);
	if(x>mid) updata(x,v,rs(p),mid+1,e);
	tr[p]=max(tr[ls(p)],tr[rs(p)]);
}

int lower(int x,int v,int p=1,int s=1,int e=n) {
	if(x<1||tr[p]<v) return 0;
	int mid=(s+e)>>1, res=0;
	if(1<=s&&e<=x) {
		if(s==e) return s;
		if(tr[rs(p)]>v) return lower(x,v,rs(p),mid+1,e);
		return lower(x,v,ls(p),s,mid);
	}
	if(x>mid) res=lower(x,v,rs(p),mid+1,e);
	if(!res) res=lower(x,v,ls(p),s,mid);
	return res;  
}

int upper(int x,int v,int p=1,int s=1,int e=n) {
//	cout << "upper " << x <<  ' ' << v << " : " << s << ' ' << e << ' ' << p <<' ' << tr[p] << '\n';
	// 查询 x 后面第一个 >v 的   
	if(x>n||tr[p]<v) return 0;
	int mid=(s+e)>>1, res=0;
	if(x<=s&&e<=n) {
		if(s==e) return s;
		if(tr[ls(p)]>v) return upper(x,v,ls(p),s,mid);
		return upper(x,v,rs(p),mid+1,e); 
	}
	if(x<=mid) res=upper(x,v,ls(p),s,mid);
	if(!res) res=upper(x,v,rs(p),mid+1,e);
	return res;
}

inline void add(int x,int v) {
	if(x<1) return;
	for( ; x<=n; x+=x&-x) bit[x]+=v;
}

inline int ask(int x=n) {
	if(x<1) return 0;
	int ret=0;
	for( ; x; x-=x&-x) ret+=bit[x];
	return ret;
} 

inline void clear() {
	ran=0;
	up(i,1,n) bit[i]=0;
}

signed main() {
	freopen("party.in","r",stdin);
	freopen("party.out","w",stdout);
	ios::sync_with_stdio(0);
	cin.tie(0);
	cin >> n;
	up(i,1,n) cin >> a[i];
	up(i,1,n) cin >> b[i];
	up(i,1,n) {
		arr[++tot]=Query(a[i],-i,b[i]);
		arr[++tot]=Query(b[i],i,a[i]);
	}
	sort(arr+1,arr+1+tot);
	up(u,1,tot) {
		int i=arr[u].i, id=arr[u].id, v=arr[u].v;
//		cout << id << ' ' << i << ' ' << v << '\n';
//		cout << "sos " << tr[1] << '\n';
		if(id>0) {
			updata(id,v);
		}
		else {
			id=-id;
			l[id]=lower(id-1,v);
			r[id]=upper(id+1,v);
//			if(id==2) cout << "ranget " << v << ' ' << l[id] << ' ' << r[id] << '\n';
//			exit(0);
		}
	}
	up(i,1,n) if(!r[i]) r[i]=n+1;
//	cout << "checklr\n"; up(i,1,n) cout << l[i] << ' ' << r[i] << '\n';
	cin >> m;
	up(i,1,m) {
		p[++ran].id=-i;
		cin >> p[ran].l >> p[ran].r;
		Ans[i]=p[ran].l-p[ran].r-1;
	}
	up(i,1,m) {
		o[++ran]=hypoxia(i,p[i].r,p[i].l);
		o[++ran]=hypoxia(-i,p[i].l-1,p[i].l); 
	}
	sort(o+1,o+1+ran);
	int j=0;
	up(i,1,ran) {
		while(j<o[i].r) ++j, add(l[j],1);
		int id=o[i].id;
		if(id>0) Ans[id]+=ask()-ask(o[i].v-1);
		else Ans[-id]-=ask()-ask(o[i].v-1);
	}
//	cout << "ans1 "; up(i,1,m) cout << Ans[i] << ' '; cout << '\n';
	
	clear();
	up(i,1,m) {
		o[++ran]=hypoxia(i,p[i].r,p[i].r);
		o[++ran]=hypoxia(-i,p[i].l-1,p[i].r);
	} j=0;
	sort(o+1,o+1+ran);
	up(i,1,ran) {
		while(j<o[i].r) ++j, add(r[j],1);
		int id=o[i].id;
		if(id>0) Ans[id]+=ask(o[i].v);
		else Ans[-id]-=ask(o[i].v);
	}
//	cout << "ans2 "; up(i,1,m) cout << Ans[i] << ' '; cout << '\n';
	
	clear(), ran=m;
	up(i,1,n) {
		p[++ran]=node(i,l[i],r[i]);
	}
	sort(p+1,p+1+ran);
	up(u,1,ran) {
		int id=p[u].id, R=p[u].r;
		if(id>0) add(R,1);
		else Ans[-id]-=ask(R);
	}
	clear();
	
	up(i,1,m) {
//		cout << "Ans = " << Ans[i] << '\n';
		if(!Ans[i]) cout << "Yes\n";
		else cout << "No\n";
	}
	
	return 0;
}
posted @ 2025-09-11 19:02  Hypoxia571  阅读(8)  评论(0)    收藏  举报