gjoi 2024.10.9

Hypoxia571發表於2024-10-10

當天在家裡躺屍看 t1 過不了就去睡覺了,還好沒寫卡場 Round 哦 /cf

怎麼有人吃錯了一整盒退高燒藥啊 /wq


T1 遊戲升級

考慮有多少 \(x\in [1,n]\) 滿足 \(b_1+\lfloor\frac{a_1}{x}\rfloor=b_2+\lfloor\frac{a_2}{x}\rfloor\),直接對下取整做整除分塊即可。gj oj 卡常所以開 long long 無法透過哦。

#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 up(i,l,r) for(register int i=l; i<=r; ++i)
#define dn(i,r,l) for(register int i=r; i>=l; --i)

using namespace std;

int t, a1, b1, a2, b2, n, Ans, ran;

void mian() {
	cin >> a1 >> b1 >> a2 >> b2 >> n, Ans=0;
	for(int l=1, r=n; l<=n; l=r+1, r=n) {
		if(a1/l) r=min(r,a1/(a1/l));
		if(a2/l) r=min(r,a2/(a2/l));
		if(b1+a1/l==b2+a2/l) Ans+=r-l+1; 
	}
	cout << Ans << '\n';
}

signed main() {
	ios::sync_with_stdio(0);
	cin.tie(0);
	cin >> t;
	while(t--) mian();
	return 0;
}

T2 難題

手玩一下發現 \(x,y\) 係數是 \(fib\) 數列的數,稍微打一下係數表只有 \(44\) 組可能的係數,設其為 \(\{(L_i,R_i)\}\)。首先除了 \(X=0\) 的情況別的 \((x,y)\) 肯定至多在一組係數中成立,所以特判之後不用考慮去重哦。

那我們現在要知道用係數對 \(L,R\) 能有多少組合法的 \(Lx+Ry=X\) 呢,用 exgcd 求出一組 \(Lx_0+Ry_0=X(d\times\frac{X}{d})\) 之後通解可以表示為 \(L(x_0+\frac{R}{d}\times k)+R(y_0-\frac{L}{d}\times k)=X\),怕超時要預處理所以寫了點莫名其妙帶 \(d\) 的東西。我們用 \(x\in[0,n],y\in[0,m]\) 的範圍去約束 \(X\) 求出合法 \(k\) 的範圍就能知道答案個數了。因為資料較大一些東西需要 i128 和自己手寫哦。

#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 __int128
#define db long double
#define up(i,l,r) for(register int i=l; i<=r; ++i)
#define dn(i,r,l) for(register int i=r; i>=l; --i)

using namespace std;

inline int read() {
    int X=0; bool flag=1; char ch=getchar();
    while(ch<'0'||ch>'9') { if(ch=='-') flag=0; ch=getchar(); }
    while(ch>='0'&&ch<='9') { X=(X<<1)+(X<<3)+ch-'0'; ch=getchar(); }
    if(flag) return X;
    return ~(X-1);
}

void write(int X) {
    if(X<0) { X=~(X-1); putchar('-'); }
    if(X>9) write(X/10);
    putchar(X%10+'0');
}

const int N=1005;

int tot=45, t, ran, n, m, Ans;
int L[N], R[N], dd[N], xx[N], yy[N]; 

int exgcd(int a,int b,int &x,int &y) {
	if(b==0) { x=1, y=0; return a; }
	int d=exgcd(b,a%b,x,y);
	int t=x; x=y, y=t-a/b*y;
	return d;
}

inline int ceil(int i,int j), floor(int i,int j);

inline int ceil(int i,int j) {
	if(j<0) i*=-1, j*=-1;
	if(i>=0) return i/j+(i%j!=0);
	return -floor(-i,j);
}

inline int floor(int i,int j) {
	if(j<0) i*=-1, j*=-1;
	if(i>=0) return i/j;
	return -ceil(-i,j);
}

void mian() {
	ran=read(), n=read(), m=read(), Ans=0;
	if(ran==0) { puts("1"); return; }
	up(i,1,tot) {
		if(ran%dd[i]) break;
		int d=dd[i], x=xx[i]*(ran/dd[i]), y=yy[i]*(ran/dd[i]);	
		int l=max(ceil (-x*d,R[i]),ceil ((y-m)*d,L[i]));
		int r=min(floor( y*d,L[i]),floor((n-x)*d,R[i]));
		if(l<=r) Ans+=r-l+1;
	}
	write(Ans), puts("");
}

signed main() {
	L[1]=R[1]=1;
	up(i,1,tot) {
		if(i>1) L[i]=L[i-1]+R[i-1], R[i]=R[i-1]+L[i];
		dd[i]=exgcd(L[i],R[i],xx[i],yy[i]);
	}
	t=read();
	while(t--) mian();
	return 0;
}

T3 迷宮逃亡

好唐哦。

貪心的想想要儘量小的邊效力,那答案應該可以在 mst 上面,預處理出 mst 之後在上面求路徑最大權即可。

問題是怎麼求 mst,暴力做什麼的就是每一個特殊點為起點做一個 bfs 連一個 \(O(p^2)\) 的巨大圖,絕對不可以呢,考慮到 mst 的特殊性,這裡面一定有大量的無用邊,起點的量級好像不是很有辦法縮小,那想辦法把起點一起做,發現會有重疊交錯哦,然後不難發現這個東西要走重疊的邊建出來是對的了,因為這個相當於列舉 \(s/t\) 往前走 \(\frac{\alpha}{2}\) 步拼在一起,跟 \(s\to t\) 長度為 \(\alpha\) 的路徑是雙射,整個過程恰好是從小到大列舉權值油滴擴充式的合併,再大的邊是無用的了喵 >w<

#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 up(i,l,r) for(register int i=l; i<=r; ++i)
#define dn(i,r,l) for(register int i=r; i>=l; --i)
#define pii pair<int,int>
#define mp make_pair
#define pb push_back

using namespace std;

const int N=200005, M=2005, K=log2(N)+5;
const int dx[4]={1,-1,0,0}, dy[4]={0,0,1,-1};

int n, m, tot, t, ran, col[M][M], dis[M][M], dsu[N], cnt;
int fa[N][K], f[N][K], dep[N];
char init[M][M];
queue<pii> q;
vector<pii> to[N];

struct node {
	int u, v, w;
	bool operator<(const node &rhs) const { return w<rhs.w; }
} p[20000005];

bool check(int i,int j) {
	if(i<1||i>n||j<1||j>m) return 0;
	return init[i][j]=='.';
}

int get(int x) {
	if(x==dsu[x]) return x;
	return dsu[x]=get(dsu[x]);
}

void dfs(int x,int fad) {
	fa[x][0]=fad, dep[x]=dep[fad]+1;
	up(i,1,ran) fa[x][i]=fa[fa[x][i-1]][i-1], f[x][i]=max(f[x][i-1],f[fa[x][i-1]][i-1]);
	for(pii qwq:to[x]) {
		int y=qwq.first, w=qwq.second;
		if(y!=fad) f[y][0]=w, dfs(y,x);
	}
}

int lca(int x,int y) {
	if(dep[x]<dep[y]) swap(x,y);
	dn(i,ran,0) if(dep[fa[x][i]]>=dep[y]) x=fa[x][i];
	if(x==y) return x;
	dn(i,ran,0) if(fa[x][i]!=fa[y][i]) x=fa[x][i], y=fa[y][i];
	return fa[x][0];
}

int upt(int x,int d) {
	int ret=0;
	dn(i,ran,0) if(dep[fa[x][i]]>=d) ret=max(f[x][i],ret), x=fa[x][i];
	return ret;
}

signed main() {
	ios::sync_with_stdio(0);
	cin.tie(0);
	cin >> n >> m >> tot >> t, ran=log2(tot);
	up(i,1,n) cin >> (init[i]+1);
	up(i,1,tot) {
		int x, y; cin >> x >> y;
		col[x][y]=i, dis[x][y]=1, q.push(mp(x,y));
	}
	while(q.size()) {
		int x=q.front().first, y=q.front().second;
		q.pop();
		up(o,0,3) {
			int xx=x+dx[o], yy=y+dy[o];
			if(!check(xx,yy)) continue;
			if(dis[xx][yy]) p[++cnt]=(node){col[x][y],col[xx][yy],dis[x][y]+dis[xx][yy]-2};
			else dis[xx][yy]=dis[x][y]+1, col[xx][yy]=col[x][y], q.push(mp(xx,yy));
		}
	}
	sort(p+1,p+1+cnt);
	up(i,1,tot) dsu[i]=i;
	up(i,1,cnt) {
		int x=get(p[i].u), y=get(p[i].v);
		if(x==y) continue;
		dsu[x]=y, to[p[i].u].pb(mp(p[i].v,p[i].w)), to[p[i].v].pb(mp(p[i].u,p[i].w));
	}
	up(i,1,tot) if(!dep[i]) dfs(i,0);
	while(t--) {
		int x, y;
		cin >> x >> y;
		if(get(x)!=get(y)) { cout << -1 << '\n'; continue; }
		int z=lca(x,y);
		cout << max(upt(x,dep[z]),upt(y,dep[z])) << '\n';
	}
	return 0;
}