當天在家裡躺屍看 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;
}