set
1.1 Description
给定一个数集 A,要求构造一个数集 B,满足:
• 对于 A 集合中任意的数 x,x 属于 B,即 A ⊆ B;
• 对于 B 集合中任意的数 a, b,(a + b) mod p 属于 B,其中 p 是一个给定的正整数。
求 B 的大小的最小值。
1.2 Input
第一行两个整数 n, p,其中 n 为 A 的大小。
第二行 n 个整数,表示数集 A 中的数,保证这些数都在 [0, p − 1] 内,保证这些数两两不
同。
1.3 Output
一个整数,表示答案。
1.4 Sample Input
2 10
4 6
1.5 Sample Output
5
1.6 Constraints
一共 10 个测试点,每个测试点 10 分,只有当你的答案与标准答案完全一致时才能得到
10 分,否则为 0 分。
测试点编号 n p 特殊限制
1 n ≤ 10 p ≤ 10
2 n ≤ 10 p ≤ 10
3 n ≤ 500 p ≤ 500
4 n ≤ 500 p ≤ 500
5 n ≤ 500 p ≤ 109 保证答案不超过 500
6 n ≤ 500 p ≤ 109 保证答案不超过 500
7 n ≤ 500 p ≤ 109 保证答案不超过 500
8 n ≤ 500 p ≤ 109
9 n ≤ 105 p ≤ 109
10 n ≤ 105 p ≤ 109
时䰤限制: 1s
オ䰤限制: 256MB
#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
int n,p;
int main(){
freopen("set.in","r",stdin);
freopen("set.out","w",stdout);
scanf("%d%d",&n,&p);
int tmp=p;
for(int x,i=1;i<=n;++i){
scanf("%d",&x);
tmp=std::__gcd(tmp,x);
}
printf("%d\n",p/tmp);
return 0;
}
sequence
2.1 Description
有一个长度为 n 的数列 A,每个数 Ai (1 ≤ i ≤ n) 都满足 1 ≤ Ai ≤ n。
我们定义这个数列的好看程度为 j − i + 1 的最大值,其中 Ai
, Ai+1, · · · , Aj 都相等。
现在你最多能操作 T 次,每次操作是将相邻的两个数交换。问该数列好看程度最大能达到
多少。
2.2 Input
第一行两个整数 n, T。
第二行 n 个整数,其中第 i 个整数表示 Ai。
2.3 Output
一个整数,表示最大能达到的好看程度。
2.4 Sample Input
7 3
3 2 2 4 3 2 3
2.5 Sample Output
3
2.6 Sample Explanation
一种最优方案是,先将最右边的一个 2 与它左边的 3 交换,再将这个 2 与它左边的 4
交换,这样好看程度为 3。
2.7 Constraints
一共 10 个测试点,每个测试点 10 分,只有当你的答案与标准答案完全一致时才能得到
10 分,否则为 0 分。
对于所有测试点,1 ≤ T ≤ n^2。
测试点编号 n 特殊限制
1 n ≤ 10 对所有 i,Ai = 1 或 Ai = 2
2 n ≤ 10 对所有 i,Ai = 1 或 Ai = 2
3 n ≤ 1000 对所有 i,Ai = 1 或 Ai = 2
4 n ≤ 1000 对所有 i,Ai = 1 或 Ai = 2
5 n ≤ 105 对所有 i,Ai = 1 或 Ai = 2
6 n ≤ 105
7 n ≤ 105
8 n ≤ 106 对所有 i,Ai = 1 或 Ai = 2
9 n ≤ 106
10 n ≤ 106
时䰤限制: 1s
オ䰤限制: 256MB
#include <stdio.h>
#include <vector>
#include <algorithm>
#define MAXN 1000005
int n;
long long T;
std::vector<int> list[MAXN];
int sum[MAXN];
int *A;
inline long long calc(int l, int r) {
int m = (l + r) >> 1;
return 1LL * A[m] * (2 * m - l - r) - (sum[m - 1] - sum[l - 1]) + (sum[r] - sum[m]) - ((m - l) * (m - l + 1) + (r - m) * (r - m + 1)) / 2;
}
inline int solve(int n) {
int i, r = 1;
for (i = 1; i <= n; i++) {
sum[i] = sum[i - 1] + A[i];
}
int ret = 0;
for (i = 1; i <= n; i++) {
if (r < i) r = i;
while (r < n && calc(i, r + 1) <= T) ++r;
ret = std::max(ret, r - i + 1);
}
return ret;
}
int main() {
freopen("seq.in", "r", stdin);
freopen("seq.out", "w", stdout);
scanf("%d%lld", &n, &T);
int i;
for (i = 1; i <= n; i++) {
int x;
scanf("%d", &x);
list[x].push_back(i);
}
int ans = 0;
for (i = 1; i <= n; i++) {
if (!list[i].empty()) {
A = &list[i].front() - 1;
ans = std::max(ans, solve(list[i].size()));
}
}
printf("%d\n", ans);
}
3 string
3.1 Description
给定三个字符串 a, b, s,它们的字符集均为小߉字⇽,即 {a, b, …, z}。
令
F0 = a
F1 = b
Fi = Fi−1 + Fi−2 (i > 1)
其中 + 表示字符串的连接。
现在有 q 个询问,每个询问给定 n, l, r,要求在由 Fn 的第 l 个到第 r 个字符组成的字
符串中,s 的出现次数。
3.2 Input
第一行一个字符串 a。
第二行一个字符串 b。
第三个一个字符串 s。
第四行一个整数 q。
接下来 q 行,每行三个整数 n, l, r,表示一个询问。
3.3 Output
对每个询问输出一行,表示该询问的答案。
3.4 Sample Input
a
b
bb
4
4 1 5
4 1 1
4 2 4
6 2 11
3.5 Sample Output
1
0
1
2
3.6 Sample Explanation
• F2 = “ba”
• F3 = “bab”
• F4 = “babba”
• F5 = “babbabab”
• F6 = “babbababbabba”
3.7 Constraints
一共 10 个测试点,每个测试点 10 分,只有当你的答案与标准答案完全一致时才能得到
10 分,否则为 0 分。
我们用 |A| 来表示字符串 A 的长度。
测试点 a b s n q 特殊限制
1 a = “a” b = “b” s = “ba” n ≤ 10 q ≤ 10 l = 1, r = |Fn|
2 a = “a” b = “b” |s| ≤ 10 n ≤ 10 q ≤ 10
3 a = “a” b = “b” |s| ≤ 1000 |Fn| ≤ 1000 q ≤ 1000 l = 1, r = |Fn|
4 |a| ≤ 1000 |b| ≤ 1000 |s| ≤ 1000 |Fn| ≤ 1000 q ≤ 1000
5 a = “a” b = “b” |s| ≤ 105
|Fn| ≤ 105
q ≤ 105
l = 1, r = |Fn|
6 |a| ≤ 105
|b| ≤ 105
|s| ≤ 105
|Fn| ≤ 105
q ≤ 105
7 a = “a” b = “b” |s| ≤ 105
|Fn| ≤ 1018 q ≤ 105
l = 1, r = |Fn|
8 a = “a” b = “b” |s| ≤ 105
|Fn| ≤ 1018 q ≤ 105
9 |a| ≤ 105
|b| ≤ 105
|s| ≤ 105
|Fn| ≤ 1018 q ≤ 105
l = 1, r = |Fn|
10 |a| ≤ 105
|b| ≤ 105
|s| ≤ 105
|Fn| ≤ 1018 q ≤ 105
时䰤限制: 1s
オ䰤限制: 256MB
//粘的题解,看不懂题解,不想写了
#include <stdio.h>
#include <string.h>
#include <string>
#include <assert.h>
#include <bits/stdc++.h>
#define debug(...) //fprintf(stderr, __VA_ARGS__)
#define MAXN 100005
#define base 313
#define mo 1000000009
using namespace std;
char a[MAXN], b[MAXN], s[MAXN];
int len_s;
int h_s;
inline void init_hash()
{
int base_pow = 1;
int i;
for (i = 0; i < len_s; i++) {
h_s = (h_s + 1LL * base_pow * s[i]) % mo;
base_pow = 1LL * base_pow * base % mo;
}
}
inline int count(const char *a, int len_a, int *sum)
{
int base_pow = 1;
int i;
int h_a = 0;
for (i = 0; i < len_s; i++) {
h_a = (h_a + 1LL * base_pow * a[i]) % mo;
base_pow = 1LL * base_pow * base % mo;
}
int ret = h_s == h_a;
sum[0] = 0;
sum[1] = ret;
int tmp_h_s = h_s;
int base_pow_2 = 1;
for (i = len_s; i < len_a; i++) {
tmp_h_s = 1LL * tmp_h_s * base % mo;
h_a = (h_a + 1LL * base_pow * a[i] - 1LL * base_pow_2 * a[i - len_s]) % mo;
h_a = (h_a + mo) % mo;
ret += tmp_h_s == h_a;
sum[i - len_s + 2] = ret;
base_pow = 1LL * base_pow * base % mo;
base_pow_2 = 1LL * base_pow_2 * base % mo;
}
return ret;
}
inline int count(const std::string &a, int *sum)
{
return count(a.c_str(), a.length(), sum);
}
int q;
std::string f[105];
long long f_len[105];
int k;
struct data {
long long ans;
int l_id, r_id;
};
int cnt2[2][2];
int sum2[2][2][MAXN*5];
int cnt[2];
int sum[2][MAXN*3];
inline data operator + (const data &a, const data &b)
{
data ret;
ret.ans = a.ans + b.ans + cnt2[a.r_id][b.l_id] - cnt[a.r_id] - cnt[b.l_id];
ret.l_id = a.l_id;
ret.r_id = b.r_id;
return ret;
}
data f_data[105];
inline void init()
{
init_hash();
cnt[0] = count(f[k - 1], sum[0]);
cnt[1] = count(f[k], sum[1]);
cnt2[0][0] = count(f[k - 1] + f[k - 1], sum2[0][0]);
cnt2[0][1] = count(f[k - 1] + f[k], sum2[0][1]);
cnt2[1][0] = count(f[k] + f[k - 1], sum2[1][0]);
cnt2[1][1] = count(f[k] + f[k], sum2[1][1]);
f_data[k - 1] = (data){cnt[0], 0, 0};
f_data[k] = (data){cnt[1], 1, 1};
int i;
for (i = k + 1; i <= 100; i++) {
f_data[i] = f_data[i - 1] + f_data[i - 2];
}
}
int _n[205], _l[205], _r[205];
int _cnt;
inline void push(int n, int l, int r)
{
debug("push %d %d %d\n", n, l, r);
++_cnt;
_n[_cnt] = n;
_l[_cnt] = l;
_r[_cnt] = r;
}
inline void _query(int n, long long l, long long r)
{
if (n <= k) {
push(n, l, r);
return;
}
if (l == 1 && r == f_len[n]) {
push(n, 0, 0);
return;
}
long long t = f_len[n - 1];
if (r <= t) {
_query(n - 1, l, r);
} else if (l > t) {
_query(n - 2, l - t, r - t);
} else {
_query(n - 1, l, t);
_query(n - 2, 1, r - t);
}
}
inline long long query(int n, long long l, long long r)
{
if (n < k - 1) {
return 0;
}
if (n <= k) {
return sum[n - k + 1][r - len_s + 1] - sum[n - k + 1][l - 1];
}
_cnt = 0;
_query(n, l, r);
if (_cnt == 1) {
// assert(_n[1] > k);
if (_n[1] <= k) {
assert(_n[1] >= k - 1);
return sum[_n[1] - k + 1][_r[1] - len_s + 1] - sum[_n[1] - k + 1][_l[1] - 1];
} else {
return f_data[_n[1]].ans;
}
} else if (_cnt == 2 && _n[1] <= k && _n[2] <= k) {
return sum2[_n[1] - k + 1][_n[2] - k + 1][_r[2] + f_len[_n[1]] - len_s + 1]
- sum2[_n[1] - k + 1][_n[2] - k + 1][_l[1] - 1];
} else {
long long ret = 0;
int L = 1, R = _cnt;
if (_n[1] <= k) {
// 1, 1-2
// assert(_n[2] > k);
ret += cnt2[_n[1] - k + 1][f_data[_n[2]].l_id] - sum2[_n[1] - k + 1][f_data[_n[2]].l_id][_l[1] - 1];
ret -= cnt[f_data[_n[2]].l_id];
L = 2;
}
if (_n[_cnt] <= k) {
// (_cnt-1)-_cnt, _cnt
// assert(_n[_cnt - 1] > k);
ret += sum2[f_data[_n[_cnt - 1]].r_id][_n[_cnt] - k + 1][_r[_cnt] + f_len[f_data[_n[_cnt - 1]].r_id + k - 1] - len_s + 1];
ret -= cnt[f_data[_n[_cnt - 1]].r_id];
R = _cnt - 1;
}
int i;
for (i = L; i <= R; i++) {
// assert(_n[i] > k);
ret += f_data[_n[i]].ans;
}
for (i = L; i < R; i++) {
ret += cnt2[f_data[_n[i]].r_id][f_data[_n[i + 1]].l_id];
ret -= cnt[f_data[_n[i]].r_id];
ret -= cnt[f_data[_n[i + 1]].l_id];
}
return ret;
}
}
int main()
{
freopen("str1.in", "r", stdin);
freopen("str.out", "w", stdout);
scanf("%s", a);
scanf("%s", b);
scanf("%s", s);
len_s = strlen(s);
f[0] = a, f[1] = b;
int i;
for (i = 2; ; i++) {
f[i] = f[i - 1] + f[i - 2];
debug("f %d = %s\n",i,f[i].c_str());
if ((int)f[i - 1].length() >= len_s) {
break;
}
}
k = i;
init();
f_len[0] = f[0].length();
f_len[1] = f[1].length();
for (i = 2; i <= 100; i++) {
f_len[i] = f_len[i - 1] + f_len[i - 2];
}
scanf("%d", &q);
for (i = 1; i <= q; i++) {
int n;
long long l, r;
scanf("%d%I64d%I64d", &n, &l, &r);
if (r - l + 1 < len_s) {
// cout<<l<<" "<<r<<" "<<r-l+1<<" "<<len_s<<endl;
puts("0");
} else {
printf("%I64d\n", query(n, l, r));
}
}
return 0;
}
三份当时的代码存档:
#include<iostream>
#include<cstring>
#include<cstdio>
#include<map>
using namespace std;
const int MAXN = 1e5+50;
const int MAXP = 1e9;
int n,Mod,a[MAXN],m,b[MAXN];
map<int,int> mp;
inline void read(int &x){
x=0; int f=1; char c=getchar();
while(c>'9'||c<'0'){ if(c=='-') f=-1; c=getchar(); }
while(c>='0'&&c<='9'){ x=x*10+c-'0'; c=getchar(); }
x*=f;
}
void solve(){
for(int i=1;i<=n;++i){
if(!mp[a[i]])
mp[a[i]]=1,b[++m]=a[i];
if(!mp[ (a[i]+a[i])%Mod ])
mp[ (a[i]+a[i])%Mod ]=1,b[++m]=(a[i]+a[i])%Mod;
}
bool flag=1;
while(flag){
flag=0;
for(int i=1;i<=m;++i)
for(int j=1;j<=m;++j)
if(!mp[ (b[i]+b[j])%Mod ])
flag=1,mp[ (b[i]+b[j])%Mod ]=1,b[++m]=(b[i]+b[j])%Mod;
}
printf("%d\n",m);
}
int main(){
freopen("set.in","r",stdin);
freopen("set.out","w",stdout);
read(n),read(Mod);
for(int i=1;i<=n;++i) read(a[i]);
if(n<=500&&Mod<=MAXP){
solve();
fclose(stdin);fclose(stdout);
return 0;
}
else if(n>500&&Mod<=MAXP){
printf("%d\n",Mod);
fclose(stdin);fclose(stdout);
return 0;
}
return 0;
}
#include<iostream>
#include<cstring>
#include<cstdio>
using namespace std;
const int MAXN = 1e6+50;
int a[MAXN],T,n,ans=1;
inline void read(int &x){
x=0; int f=1; char c=getchar();
while(c>'9'||c<'0'){ if(c=='-') f=-1; c=getchar(); }
while(c>='0'&&c<='9'){ x=x*10+c-'0'; c=getchar(); } x*=f;
}
inline void UpDate(){
for(int i=1;i<=n;){
int cur=i+1;
while(cur<=n&&a[cur]==a[cur-1]) ++cur;
ans=max(ans,cur-i);
i=cur;
}
}
void DFS(int t){
if(!t) return;
UpDate();
for(int i=1;i<n;++i){
if(a[i]!=a[i+1]){
swap(a[i],a[+1]);
DFS(t-1);
swap(a[i],a[i+1]);
}
}
for(int i=2;i<=n;++i){
if(a[i]!=a[i-1]){
swap(a[i],a[-1]);
DFS(t-1);
swap(a[i],a[i-1]);
}
}
}
int main(){
freopen("seq.in","r",stdin);
freopen("seq.out","w",stdout);
read(n),read(T);
for(int i=1;i<=n;++i) read(a[i]);
DFS(T);
printf("%d\n",ans);
return 0;
}
#include<iostream>
#include<cstring>
#include<cstdio>
#include<string>
using namespace std;
string a1,b1,c,s,a,b;
int n,q,l,r;
int calc(){
int ans=0;
if(r-l+1<s.length()) return 0;
for(int i=l-1;i<=(r-1)-s.length()+1;++i)
for(int j=0;j<s.length();++j){
if(s[j]==c[i+j]&&j==s.length()-1){ ++ans; continue; }
if(s[j]!=c[i+j]) break;
}
return ans;
}
int main(){
freopen("str.in","r",stdin);
freopen("str.out","w",stdout);
cin>>a1>>b1>>s;
scanf("%d",&q);
for(int i=1;i<=q;++i){
scanf("%d%d%d",&n,&l,&r);
a=a1,b=b1;
for(int j=1;j<=n-1;++j)
c=b+a,a=b,b=c;
printf("%d\n",calc());
}
return 0;
}