gjoi 9.19

Hypoxia571發表於2024-09-20

常數太大掛分絕美哈,感覺是 oj 不帶 o2 但是我用了不少吸氧才快點的東西。


T1 困難卷積

\(O(n\sqrt n)\) 感覺跑的太不過了,注意到 \(\sum a_i,\sum b_i\leq 10^7\),我們不妨讓大 \(a/b\) 的找小的 \(b/a\) 貢獻,這樣子複雜度是 \(O(\sum\sqrt{a_i}+\sum\sqrt{b_i})\) 的,輕鬆透過此題。

#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=3000005;

int n, a[N], b[N], limit, Ans, cnt[N];

void solve() {
	up(i,0,limit) cnt[i]=0;
	up(i,1,n) ++cnt[b[i]];
	up(i,1,limit) cnt[i]+=cnt[i-1];
	up(i,1,n) for(int x=1; x*x<=a[i]; ++x) Ans+=cnt[a[i]-x*x];
}

signed main() {
	ios::sync_with_stdio(0);
	cin.tie(0);
	cin >> n;
	up(i,1,n) cin >> a[i], limit=max(limit,a[i]);
	up(i,1,n) cin >> b[i], limit=max(limit,b[i]);
	solve();
	up(i,1,n) swap(a[i],b[i]);
	solve();
	cout << Ans;
	return 0;
}

T2 點集直徑

先計算全放 \(x/y\) 的貢獻,剩下橫縱軸都有的情況,此時貢獻有 3 種產生方式,在 \(x/y\) 軸的極差,\(x\) 上絕對值最大的和 \(y\) 上絕對值最大的組成的斜線。考慮二分答案 \(dis\) 判斷可行性,列舉貢獻 \(x\) 絕對值最大的點 \(p\),設其座標為 \((x_0,y_0)\)

  • \(x_0\geq 0\),則 \(x\in[max(-x_0,x_0-dis),x_0]\) 的放到 \(x\) 軸,否則只能放到 \(y\) 軸。

  • \(x_0<0\),則 \(x\in[x_0,min(-x_0,x_0+dis)]\) 的放到 \(x\) 軸,否則只能放到 \(y\) 軸。

找合法區間可以使用兩個雙指標 / 二分+o2 最佳化,lower_bound 不吸氧會 100-> 50 /fad

然後判定還要預處理一個前/字尾最大/小值域,注意初始化,還有就是自帶的 sqrt 掉精度嚴重要手寫。

#define _CRT_SECURE_NO_WARNINGS
#pragma GCC optimize(2)
#pragma GCC optimize(3)
#pragma GCC optimize("Ofast")
#pragma GCC optimize("inline")
#pragma GCC optimize("-fgcse")
#pragma GCC optimize("-fgcse-lm")
#pragma GCC optimize("-fipa-sra")
#pragma GCC optimize("-ftree-pre")
#pragma GCC optimize("-ftree-vrp")
#pragma GCC optimize("-fpeephole2")
#pragma GCC optimize("-ffast-math")
#pragma GCC optimize("-fsched-spec")
#pragma GCC optimize("unroll-loops")
#pragma GCC optimize("-falign-jumps")
#pragma GCC optimize("-falign-loops")
#pragma GCC optimize("-falign-labels")
#pragma GCC optimize("-fdevirtualize")
#pragma GCC optimize("-fcaller-saves")
#pragma GCC optimize("-fcrossjumping")
#pragma GCC optimize("-fthread-jumps")
#pragma GCC optimize("-funroll-loops")
#pragma GCC optimize("-fwhole-program")
#pragma GCC optimize("-freorder-blocks")
#pragma GCC optimize("-fschedule-insns")
#pragma GCC optimize("inline-functions")
#pragma GCC optimize("-ftree-tail-merge")
#pragma GCC optimize("-fschedule-insns2")
#pragma GCC optimize("-fstrict-aliasing")
#pragma GCC optimize("-fstrict-overflow")
#pragma GCC optimize("-falign-functions")
#pragma GCC optimize("-fcse-skip-blocks")
#pragma GCC optimize("-fcse-follow-jumps")
#pragma GCC optimize("-fsched-interblock")
#pragma GCC optimize("-fpartial-inlining")
#pragma GCC optimize("no-stack-protector")
#pragma GCC optimize("-freorder-functions")
#pragma GCC optimize("-findirect-inlining")
#pragma GCC optimize("-fhoist-adjacent-loads")
#pragma GCC optimize("-frerun-cse-after-loop")
#pragma GCC optimize("inline-small-functions")
#pragma GCC optimize("-finline-small-functions")
#pragma GCC optimize("-ftree-switch-conversion")
#pragma GCC optimize("-foptimize-sibling-calls")
#pragma GCC optimize("-fexpensive-optimizations")
#pragma GCC optimize("-funsafe-loop-optimizations")
#pragma GCC optimize("inline-functions-called-once")
#pragma GCC optimize("-fdelete-null-pointer-checks")
#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=200005, inf=1e18;

int n, Ans, x[N], y[N], fx[N], fy[N], gx[N], gy[N];
struct node {
	int x, y;
	bool operator<(const node &rhs) const { return x<rhs.x; } 
} p[N];

inline int sq(int x) { return x*x; }

inline int sqrt(int x) {
    if(x<1) return 0;
	int l=0, r=x, ret;
	while(l<=r) {
		int mid=(l+r)/2;
		if(mid<=x/mid) ret=mid, l=mid+1;
		else r=mid-1; 
	}
	return ret;
}

bool check(int dis) {
	int qwq=sqrt(dis);
	up(i,1,n) {
		int L, R, U=-inf, D=inf;
		if(p[i].x>=0) R=p[i].x, L=max(-R,R-qwq); else L=p[i].x, R=min(-L,L+qwq);
		L=lower_bound(x+1,x+1+n,L)-x, R=upper_bound(x+1,x+1+n,R)-x-1;
		if(L>1) U=max(fx[L-1],U), D=min(fy[L-1],D);
		if(R<n) U=max(gx[R+1],U), D=min(gy[R+1],D);
		if((L>1||R<n)&&sq(U-D)<=dis&&sq(max(abs(U),abs(D)))+sq(p[i].x)<=dis) return 1;  
	}
	return 0;
}

signed main() {
	ios::sync_with_stdio(0);
	cin.tie(0);
	cin >> n;
	up(i,1,n) cin >> p[i].x >> p[i].y;
	sort(p+1,p+1+n), fy[0]=gy[n+1]=inf, fx[0]=gx[n+1]=-inf;
	up(i,1,n) x[i]=p[i].x, y[i]=p[i].y;
	up(i,1,n) fx[i]=max(fx[i-1],y[i]), fy[i]=min(fy[i-1],y[i]);
	dn(i,n,1) gx[i]=max(gx[i+1],y[i]), gy[i]=min(gy[i+1],y[i]);
	Ans=min(sq(p[n].x-p[1].x),sq(fx[n]-fy[n]));
	int l=0, r=Ans;
	while(l<=r) {
		int mid=(l+r)/2;
		if(check(mid)) Ans=min(Ans,mid), r=mid-1;
		else l=mid+1;
	}
	cout << Ans;
	return 0;
}

T3 對稱之美

#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;

int mul(int a,int b,int mod) {
	int ret=0;
	a=(a%mod+mod)%mod, b=(b%mod+mod)%mod;
	for( ; b; b>>=1) {
		if(b&1) ret=(ret+a)%mod;
		a=(a+a)%mod;
	}
	return (ret%mod+mod)%mod;
}

int ksm(int a,int b,int mod) {
	int ret=1%mod;
	a=(a%mod+mod)%mod;
	for( ; b; b>>=1) {
		if(b&1) ret=mul(ret,a,mod);
		a=mul(a,a,mod);
	}
	return (ret%mod+mod)%mod;
}

int t, m, p;

signed main() {
	ios::sync_with_stdio(0);
	cin.tie(0);
	cin >> t;
	while(t--) {
		cin >> p >> m;
		if(p<=2) { cout << 1 << '\n'; continue; }
		int t=((1-mul(4,m,p))%p+p)%p;
		cout << ksm(t,(p-1)/2,p) << '\n';
	}
	return 0;
}

T4 王道征途

不難發現時間倒流之後是模板線段樹,注意常數,注意如果在沒有被佔領的洞裡面出現寶物不會留存(這個題面真的很沒有素質,而且大樣例也沒有 \(a_i=0\) 吧)。

#define _CRT_SECURE_NO_WARNINGS
#pragma GCC optimize(2)
#pragma GCC optimize(3)
#pragma GCC optimize("Ofast")
#pragma GCC optimize("inline")
#pragma GCC optimize("-fgcse")
#pragma GCC optimize("-fgcse-lm")
#pragma GCC optimize("-fipa-sra")
#pragma GCC optimize("-ftree-pre")
#pragma GCC optimize("-ftree-vrp")
#pragma GCC optimize("-fpeephole2")
#pragma GCC optimize("-ffast-math")
#pragma GCC optimize("-fsched-spec")
#pragma GCC optimize("unroll-loops")
#pragma GCC optimize("-falign-jumps")
#pragma GCC optimize("-falign-loops")
#pragma GCC optimize("-falign-labels")
#pragma GCC optimize("-fdevirtualize")
#pragma GCC optimize("-fcaller-saves")
#pragma GCC optimize("-fcrossjumping")
#pragma GCC optimize("-fthread-jumps")
#pragma GCC optimize("-funroll-loops")
#pragma GCC optimize("-fwhole-program")
#pragma GCC optimize("-freorder-blocks")
#pragma GCC optimize("-fschedule-insns")
#pragma GCC optimize("inline-functions")
#pragma GCC optimize("-ftree-tail-merge")
#pragma GCC optimize("-fschedule-insns2")
#pragma GCC optimize("-fstrict-aliasing")
#pragma GCC optimize("-fstrict-overflow")
#pragma GCC optimize("-falign-functions")
#pragma GCC optimize("-fcse-skip-blocks")
#pragma GCC optimize("-fcse-follow-jumps")
#pragma GCC optimize("-fsched-interblock")
#pragma GCC optimize("-fpartial-inlining")
#pragma GCC optimize("no-stack-protector")
#pragma GCC optimize("-freorder-functions")
#pragma GCC optimize("-findirect-inlining")
#pragma GCC optimize("-fhoist-adjacent-loads")
#pragma GCC optimize("-frerun-cse-after-loop")
#pragma GCC optimize("inline-small-functions")
#pragma GCC optimize("-finline-small-functions")
#pragma GCC optimize("-ftree-switch-conversion")
#pragma GCC optimize("-foptimize-sibling-calls")
#pragma GCC optimize("-fexpensive-optimizations")
#pragma GCC optimize("-funsafe-loop-optimizations")
#pragma GCC optimize("inline-functions-called-once")
#pragma GCC optimize("-fdelete-null-pointer-checks")
#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)

using namespace std;

const int N=500005;

int n, m, q, opt[N], a[N], L[N], R[N], X[N], Ans[N];
int tag[N<<2], add[N<<2], val[N<<2];

inline void tup(int p) {
	val[p]=val[ls(p)]+val[rs(p)];
}

inline void tdn(int p,int s,int e) {
	if(tag[p]) {
		tag[ls(p)]=1, val[ls(p)]=0, add[ls(p)]=0;
		tag[rs(p)]=1, val[rs(p)]=0, add[rs(p)]=0; 
		tag[p]=0;
	}
	if(add[p]) {
		int mid=(s+e)>>1;
		val[ls(p)]+=add[p]*(mid-s+1), add[ls(p)]+=add[p];
		val[rs(p)]+=add[p]*(e-mid), add[rs(p)]+=add[p];
		add[p]=0; 
	}
}

void Add(int l,int r,int v,int p=1,int s=1,int e=n) {
	if(l<=s&&e<=r) {
		val[p]+=(e-s+1)*v, add[p]+=v;
		return;
	}
	tdn(p,s,e);
	int mid=(s+e)>>1;
	if(l<=mid) Add(l,r,v,ls(p),s,mid);
	if(r>mid) Add(l,r,v,rs(p),mid+1,e);
	tup(p);
}

void Clear(int l,int r,int p=1,int s=1,int e=n) {
	if(l<=s&&e<=r) {
		val[p]=add[p]=0, tag[p]=1;
		return;
	}
	tdn(p,s,e);
	int mid=(s+e)>>1;
	if(l<=mid) Clear(l,r,ls(p),s,mid);
	if(r>mid) Clear(l,r,rs(p),mid+1,e);
	tup(p);
}

int Ask(int l,int r,int p=1,int s=1,int e=n) {
	if(l<=s&&e<=r) return val[p];
	tdn(p,s,e);
	int mid=(s+e)>>1, ret=0;
	if(l<=mid) ret+=Ask(l,r,ls(p),s,mid);
	if(r>mid) ret+=Ask(l,r,rs(p),mid+1,e);
	return ret;
}

signed main() {
	ios::sync_with_stdio(0);
	cin.tie(0);
	cin >> n >> m >> q;
	up(i,1,n) cin >> a[i];
	up(i,1,q) cin >> opt[i] >> L[i] >> R[i] >> X[i];
	dn(i,q,1) {
		if(opt[i]==1) {
			Ans[X[i]]+=Ask(L[i],R[i]);
			Clear(L[i],R[i]);
		}
		else Add(L[i],R[i],X[i]);
	}
	up(i,1,n) if(a[i]) Ans[a[i]]+=Ask(i,i);
	up(i,1,m) cout << Ans[i] << '\n';
	return 0;
}