国庆清北刷题冲刺班 Day4 上午

95 篇文章 1 订阅
75 篇文章 0 订阅

a

【问题描述】
你是能看到第一题的friends呢。
——hja

Hja拥有一套时光穿梭技术,能把字符串以超越光速的速度传播,但是唯一的问题是可能会GG。在传输的过程中,可能有四种情况:
1、 字符串没有发生改变。
2、 字符串的某一位由0变1或者由1变0。
3、 某一位消失了。
4、 多了一位。
为了防止字符串GG,Hja保证发送的字符串只由01组成,并且所有字符串开始的长度均为 ,并且所有为1的位置的下标之和一定是 的倍数。在给定了你这些条件之后,Hja告诉你传输之后的字符串,并按照以下规则复原字符串:
1、 对于一个字符串,按照四种规则从前到后的优先级依次尝试能否复原为一个合法的字符串。
2、 对于同一种操作,更靠前的位置更加优先。
3、 对于同一种操作的同一位置,0比1更加优先。
4、 如果没有任何一种方法复原字符串,则输出 。
【输入格式】
第一行一个整数 ,代表所有字符串的长度。
接下来若干行,每行一个字符串。
【输出格式】
对于每个字符串,输出一行代表答案。
【样例输入】
4
0000
011
1011
11011
【样例输出】
0000
0110
1001
1111
【数据范围与规定】
对于 的数据, ,字符串数量不超过 。

略恶心的模拟, 考场爆零,直接GG

#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
using namespace std;
#define MAXN 2005
int n,num[MAXN];
char s[MAXN];

bool check1(char *s){
    int len = strlen(s+1);
    if(len != n) return false;
    int Sum = 0;
    for(int i=1; i<=n; ++i) if(s[i] == '1') Sum += i;
    for(int i=1; i<=n; ++i)
        if(s[i] == '1'){
            Sum -= i;
            if(Sum % (n+1) == 0){
                s[i] = '0';
                printf("%s\n",s+1);
                return true;
            }
            Sum += i;
        }
    return false;
}

bool check4(char *s){
    int len = strlen(s+1);
    if(len != n) return false;
    int Sum = 0;
    for(int i=1; i<=len; ++i) if(s[i] == '1') Sum += i;
    if(Sum % (n+1) == 0){
        printf("%s\n",s+1);
        return true;
    }
    return false;
}

bool check3(char *s){//多了一位   ---- >  消掉 
    int len = strlen(s+1);
    if(len != n+1) return false;
    int Sum = 0;
    for(int i=1; i<=len; ++i) {
        num[i] = num[i-1];
        if(s[i] == '1') Sum += i,++num[i];
    }
    for(int i=1; i<=len; ++i){
        Sum -= num[len] - num[i];
        if(s[i] == '1') Sum -= i;
        if(Sum % (n+1) == 0){
            for(int j=1; j<i; ++j) printf("%c",s[j]);
            for(int j=i+1; j<=len; ++j) printf("%c",s[j]);
            printf("\n");
            return true;
        }
        Sum += num[len] - num[i];
        if(s[i] == '1') Sum += i;
    }
    return false;
}

bool check2(char *s){
    int len = strlen (s+1);
    if(len != n-1) return false;
    int Sum = 0;
    for(int i=1; i<=len; ++i){
        num[i] = num[i-1];
        if(s[i] == '1') Sum += i,++num[i];
    }
    for(int i=1; i<=n; ++i){
        Sum += num[len] - num[i-1];
        if(Sum % (n+1) == 0){
            for(int j=1; j<i; ++j) printf("%c",s[j]);
            printf("0");
            for(int j=i; j<=len; ++j) printf("%c",s[j]);
            printf("\n");
            return true;
        }
        Sum += i;
        if(Sum % (n+1) == 0){
            for(int j=1; j<i; ++j) printf("%c",s[j]);
            printf("1");
            for(int j=i; j<=len; ++j) printf("%c",s[j]);
            printf("\n");
            return true;
        }
        Sum -= i + num[len] - num[i-1];
    }
    return false;
}


int main(int argc,char *argv[]){
    freopen("a.in","r",stdin);
    freopen("a.out","w",stdout);
    scanf("%d",&n);
    while(~scanf("%s",s+1)){
        bool ok = false;
        ok = check4(s);
        if(ok) continue;
        ok = check1(s);
        if(ok) continue;
        ok = check2(s);
        if(ok) continue;
        ok = check3(s);
        if(ok) continue;
        printf("-1\n");
    }
    fclose(stdin);fclose(stdout);
    return 0;
}

b

【问题描述】
你是能看到第二题的friends呢。
——laekov

Hja和Yjq在玩游戏,这个游戏中Hja给了Yjq两个数 ,希望Yjq找到一些非负整数使得这些数的和等于 ,并且所有数模 的值互不相同,求方案数。
【输入格式】
一行两个整数 。
【输出格式】
一行一个整数代表答案对 取模之后的结果。
【样例输入1】
3 3
【样例输出1】
9
【样例输入2】
523 44
【样例输出2】
338398304
【数据范围与规定】
对于 的数据, 。
对于 的数据, 。
对于 的数据, 。
对于 的数据, 。

这道题并不是原题。
题解来自:http://blog.csdn.net/samjia2000/article/details/47451087

#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
#include<cstdlib>

using namespace std;
#define LL long long
#define Mod 905229641
#define MAXN 110
LL n,m,f[MAXN][MAXN * MAXN],fac[MAXN];

void Prepare(){
    f[0][0] = 1;
    for(int i=0; i<=m-1; ++i)
        for(int j=i; j>=0; --j)
            for(int k=0; k<=m*(m-1)/2-i; ++k)
                if(f[j][k]) f[j+1][k+i] = (f[j][k] + f[j+1][k+i]) % Mod;
    fac[1] = 1;
    for(int i=2; i<=m; ++i) fac[i] = fac[i-1] * i % Mod;
}

LL Fast_Pow(LL x,int b){
    LL ret = 1;
    while(b){
        if(b & 1) ret = (ret * x) % Mod;
        x = (x * x) % Mod,b >>= 1;
    }
    return ret;
}

int main(int argc,char *argv[]){
    freopen("b.in","r",stdin);
    freopen("b.out","w",stdout);
    scanf("%I64d%I64d",&n,&m);
    Prepare();
    LL Ans = 0;
    for(int i=0; i<=m*(m-1)/2; ++i)
        if((n-i) % m == 0){
            LL x = ((n - i) / m) % Mod;
            LL tot = 1;
            for(int j=1; j<=m; ++j){
                Ans = (Ans + f[j][i] * fac[j] % Mod * tot % Mod) % Mod;
                tot = (tot * (x + j) % Mod * Fast_Pow(j,Mod-2) % Mod) % Mod;
            }
        }
    printf("%I64d\n",Ans);
    fclose(stdin); fclose(stdout);
    return 0;
}

c

【问题描述】
你是能看到第三题的friends呢。
——aoao

Hja回到老家开始种地,由于太久没有种地,所以所有地都是荒地。将每片地从荒地变成不荒地有一定的代价,但是一旦改变之后就不再是荒地了。现在Hja要开始 年的种地生活,第 年Hja可以在 到 块地上种地,并且可以获得 的收益。(注意,要种地必须整段一起种,并且这些地一定已经是不荒地)Hja可以选择种或者不种每一年的地,问Hja能够获得的最大收益。
【输入格式】
第一行两个整数 ,代表地的数量和年数。
接下来一行 个数,代表每块地变成不荒地的代价。
接下来 行,每行三个整数 如题意描述。
【输出格式】
一行一个整数代表答案。
【样例输入】
7 4
3 2 3 2 1 2 3
1 2 5
2 3 5
3 5 3
7 7 5
【样例输出】
4
【数据规模与约定】
对于 的数据, 。
对于 的数据, 。

线段树优化DP,种地时间其实对本题并没有任何影响

//附上 zhx 的代码
#include <cstdio>
#include <cctype>
#include <memory.h>
#include <algorithm>

using namespace std;

typedef long long qw;

#ifdef WIN32
#define lld "%I64d"
#else
#define lld "%lld"
#endif

int nextInt() {
    int s = 0, d;
    bool nag = 0;
    do {
        d = getchar();
        if (d == '-')
            nag = 1;
    } while (!isdigit(d));
    do
        s = s * 10 + d - 48, d = getchar();
    while (isdigit(d));
    return nag ? -s : s;
}

struct seg {
    int l, r;
    qw v, z;
    seg *ls, *rs;
};
struct obj {
    int l, r, v;
};

inline bool cmpObj(const obj& a, const obj& b) {
    return (a. l < b. l) || (a. l == b. l && a. r < b. r);
}

const int maxn = 200009;
const qw inf = 0x3f3f3f3f3f3f3f3fLL;

int n, m;
obj q[maxn];
qw s[maxn], ans;
seg *rtf, *rtc, *sp;

#define mid(p) ((p->l+p->r)>>1)

seg *sgtBuild(int l, int r) {
    seg *p = sp ++;
    p-> v = - inf;
    p-> z = 0;
    p-> l = l;
    p-> r = r;
    if (l + 1 < r) {
        p-> ls = sgtBuild(l, mid(p));
        p-> rs = sgtBuild(mid(p), r);
    }
    return p;
}

void sgtChg(seg* p, int p0, qw v0) {
    if (p-> l + 1 == p-> r)
        p-> v = max(p-> v, v0);
    else {
        if (p0 < mid(p))
            sgtChg(p-> ls, p0, v0 - p-> z);
        else
            sgtChg(p-> rs, p0, v0 - p-> z);
        p-> v = max(p-> ls-> v, p-> rs-> v) + p-> z;
    }
}

qw sgtQry(seg* p, int l, int r) {
    if (l >= r)
        return -inf;
    else if (p-> l == l && p-> r == r)
        return p-> v;
    else if (r <= mid(p))
        return sgtQry(p-> ls, l, r) + p-> z;
    else if (l >= mid(p))
        return sgtQry(p-> rs, l, r) + p-> z;
    else
        return max(sgtQry(p-> ls, l, mid(p)), sgtQry(p-> rs, mid(p), r)) + p-> z;
}

void sgtLazy(seg* p, int l, qw z0) {
    if (p-> v == -inf)
        return;
    else if (p-> l == l)
        p-> v += z0, p-> z += z0;
    else {
        if (l < mid(p)) {
            sgtLazy(p-> ls, l, z0);
            sgtLazy(p-> rs, mid(p), z0);
        }
        else
            sgtLazy(p-> rs, l, z0);
        p-> v = max(p-> ls-> v, p-> rs-> v) + p-> z;
    }
}

int main() {
    freopen("c.in","r",stdin);
    freopen("c.out","w",stdout);
    sp = new seg[maxn * 6];
    n = nextInt();
    m = nextInt();
    rtf = sgtBuild(0, n + 2);
    rtc = sgtBuild(0, n + 2);
    s[0] = 0;
    for (int i = 1; i <= n; i ++)
        s[i] = s[i - 1] + nextInt();
    for (int i = 0; i < m; i ++) {
        q[i]. l = nextInt();
        q[i]. r = nextInt();
        q[i]. v = nextInt();
    }
    sort(q, q + m, cmpObj);
    ans = 0;
    for (int i = 0; i < m; i ++) {
        qw res0 = max(sgtQry(rtf, 0, q[i]. l), 0LL) - s[q[i]. r] + s[q[i]. l - 1];
        qw res1 = sgtQry(rtc, q[i]. l, q[i]. r + 1) - s[q[i]. r];
        qw res = max(max(res0, res1), sgtQry(rtf, q[i]. r, n + 1)) + q[i]. v;
        sgtLazy(rtf, q[i]. r, q[i]. v);
        sgtLazy(rtc, q[i]. r, q[i]. v);
        sgtChg(rtf, q[i]. r, res);
        sgtChg(rtc, q[i]. r, res + s[q[i]. r]);
        ans = max(ans, res);
    }
    printf(lld "\n", ans);
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

七情六欲·

学生党不容易~

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

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

打赏作者

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

抵扣说明:

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

余额充值