题解-[省选联考 2024] 季风
题意:
给定 \(n,k,x,y\) 和 \(2n\) 个整数 \(x_0,y_0,x_1,y_1,\dots,x_{n-1},y_{n-1}\)。
找到最小的非负整数 \(m\),使得存在 \(2m\) 个实数 \(x_0',y_0',x_1',y_1',\dots,x_{m-1}',y_{m-1}'\) 满足以下条件,或报告不存在这样的 \(m\):
- \(\sum \limits_{i=0}^{m-1} (x_i'+x_{i \bmod n})=x\);
- \(\sum \limits_{i=0}^{m-1} (y_i'+y_{i \bmod n})=y\);
- \(\forall 0\leq i\leq m-1,|x_i'|+|y_i'|\leq k\)。
- 特别地,\(m=0\) 时,认为 \(\sum \limits_{i=0}^{m-1} (x_i'+x_{i \bmod n})\) 和 \(\sum \limits_{i=0}^{m-1} (y_i'+y_{i \bmod n})\) 均为 \(0\)。
思路:
\(\forall 0\leq i\leq m-1,|x_i'|+|y_i'|\leq k\) \(\iff\) \(\sum \limits_{i=0}^{m-1}| x_i'| + \sum \limits_{i=0}^{m-1}|y_i'| \le m \times k\)。
移项可得 \(\sum \limits_{i=0}^{m-1} x_i'=x - \sum \limits_{i=0}^{m-1} x_{i \bmod n}\) , \(\sum \limits_{i=0}^{m-1} y_i'=y - \sum \limits_{i=0}^{m-1} y_{i \bmod n}\)。
所以题目的限制条件就变成了 $ |x - \sum \limits_{i=0}^{m-1} x_{i \bmod n}| + |y - \sum \limits_{i=0}^{m-1} y_{i \bmod n}| \le m \times k$。
发现这个下标为 \(i \bmod n\),那不妨记 \(m = t\times n + q\)。
那么原式子可以变成 $ |x - \sum \limits_{i=0}^{n-1} x_i \times t - \sum \limits_{i=0}^{q-1} x_i| + |y - \sum \limits_{i=0}^{n-1} y_i \times t - \sum \limits_{i=0}^{q-1} y_i| \le (t\times n + q) \times k$。
因为 \(q \in [0 , n-1]\),那么直接枚举 \(q\),原式就是一个关于 \(t\) 的不等式,直接解即可,时间复杂度 \(O(n)\)。
代码:
#include<bits/stdc++.h>
#define rep(i,a,n) for(int i=(a);i<=(n);i++)
#define per(i,a,n) for(int i=(n);i>=(a);i--)
#define pb push_back
#define fi first
#define se second
using namespace std;
typedef long long ll;
typedef double db;
typedef pair<ll,ll> pll;
template<typename T>
inline void pr(T x,bool op=false){
x<0?x=-x,putchar('-'):0;
static short sta[25],top(0);
do sta[top++]=x%10,x/=10; while(x);
while(top) putchar(sta[--top]|48);
op?putchar('\n'):putchar(' ');
}
template<class T> void rd(T &x){
char c; bool f = 0;
while(((c = getchar()) < '0' || c > '9') && c != '-');
if(c == '-'){f = 1; c = getchar();}
x = c - '0';
while((c = getchar()) >= '0' && c <= '9')x = x * 10 + c - '0';
if(f) x = -x;
}
const int maxn=1e6+10;
const ll inf=4e18;
int n,k,x,y,a[maxn],b[maxn];
ll prea,preb,sa,sb;
inline pll calc(ll x,ll y){
if(!x){
if(y>=0) return {-inf,inf};
else return {inf,-inf};
}
else{
if(x<0){
if(!y) return {0,inf};
if(y<0) return {((-y)+(-x)-1)/(-x),inf};
if(y>0) return {-(y/(-x)),inf};
}
if(x>0){
if(!y) return {-inf,0};
if(y<0) return {-inf,-(((-y)+x-1)/x)};
if(y>0) return {-inf,y/x};
}
}
return {-inf,inf};
}
inline void solveall(){
ll ans=inf;
rep(i,0,n-1){
ll l=-inf,r=inf;
pll now;
now=calc(-sa-sb-1ll*n*k,1ll*i*k-x-y+prea+preb); l=max(l,now.fi); r=min(r,now.se);
now=calc(-sa+sb-1ll*n*k,1ll*i*k-x+y+prea-preb); l=max(l,now.fi); r=min(r,now.se);
now=calc( sa-sb-1ll*n*k,1ll*i*k+x-y-prea+preb); l=max(l,now.fi); r=min(r,now.se);
now=calc( sa+sb-1ll*n*k,1ll*i*k+x+y-prea-preb); l=max(l,now.fi); r=min(r,now.se);
if(l<=r && r>=0) ans=min(ans,max(l,0ll)*n+i);
prea+=a[i]; preb+=b[i];
}
if(ans==inf) ans=-1;
pr(ans,1);
}
inline void solve(){
sa=sb=prea=preb=0;
rd(n); rd(k); rd(x); rd(y);
rep(i,0,n-1){
rd(a[i]),rd(b[i]);
sa+=a[i]; sb+=b[i];
}
if(!x && !y) pr(0,1);
else solveall();
}
signed main(){
int _=1;
rd(_);
while(_--) solve();
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现