2017.9.5模拟考试

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;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

七情六欲·

学生党不容易~

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值