鸽巢原理运用
给定长为 的序列 ,求一组 使得 。
第一行输入 ;
第二行输入 个数字,表示序列 。
输出
保证 。
保证数据在 范围内。
题解:证明存在性。若 中有任何一个可以被 整除那么结论就成立。设这 个和模 的余数为 ,因为 的值只能是 ,所以定有两个余数相同,这里用到鸽巢原理。
设这两个相同余数为 和 。我们将其作差得到 ,故 能被 整除。
那么这就优化了暴力枚举,我们用前缀和判同余即可,时间复杂度达到 。
代码:
#include <bits/stdc++.h>
#define rei register int
#define ll long long
#define IOS ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
#define rep(i, s, n, c) for (register int i = s; i <= n; i+=c)
#define repd(i, s, n, c) for (register int i = s; i >= n; i-=c)
#define CHECK cout<<"WALKED"<<endl;
inline int read(){int x=0,f=1;char ch=getchar();while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();} while(ch>='0' && ch<='9')x=(x<<3)+(x<<1)+ch-'0',ch=getchar();return x*f;}
#define pb push_back
#define ls id<<1
#define rs id<<1|1
const int INF = INT_MAX;
long long binpow(long long a, long long b, ll mod){long long res = 1; while (b > 0){if (b & 1) res = res * a % mod;a = a * a % mod; b >>= 1; } return res;}
using namespace std;
int a[200005], b[200005];
int main()
{
int m = read();
rep (i, 1, m, 1) {
a[i] = read();
a[i] += a[i - 1];
}
rep (i, 1, m, 1) {
int r = a[i] % m;
if (!b[r]) {
b[r] = i + 1;
} else {
printf("%d %d\n", b[r], i);
break;
}
}
return 0;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
· 25岁的心里话