牛客OI周赛13-提高组 比赛总结

比赛情况

1h才写出T1 100pts + T2 50pts(都是简单dp可还行)。然后就去颓废了。颓废完来康康T3的暴力,wow,T3咋这么难呢!?期望概率好像不太会了,退了吧qwq。

所以最后 100+50+0=150pts, rank 22。

比赛总结

  • 说实话比赛前还有些紧张呢,但是我这次吸取了经验,牢记dalao之前对我讲的,“花2h肝T1,T2是值得的。”(CSP-S就是因为花2h+肝T3暴力,让我留下了终身的遗憾),于是安心写T1,T2,稳扎稳打拿下150pts

  • 在这次比赛学到了一个简单的树状数组优化dp。

T1 0还是1

定义 f[i,0/1] 表示使用完前 i 个运算符后结果为 0/1 的方案总数,分当前位是 0还是1 讨论。

入门级别的dp题放在tgT1合不合适呢,我想放在 CSP-S D1T1 可能还合适吧qwq

Talk is cheap.Show me the code.

#include<bits/stdc++.h>
#define int long long
using namespace std;
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^48); ch=getchar(); }
    return x * f;
}
const int N = 1e7, MOD = 1e9+7;
int n;
int f[N][2];
char s[N];
signed main()
{
    //freopen("a.in","r",stdin);
    n = read();
    scanf("%s",s+1);
    f[0][0] = f[0][1] = 1;
    for(int i=1;i<=n;++i) {
        if(s[i] == '&') {
            f[i][0] = (((2*f[i-1][0])%MOD) + f[i-1][1])%MOD;
            f[i][1] = (f[i-1][1])%MOD;
        } else if(s[i] == '|') {
            f[i][0] = (f[i-1][0])%MOD;
            f[i][1] = (((2*f[i-1][1])%MOD) + f[i-1][0])%MOD;
        } else if(s[i]=='^') {
            f[i][0] = (f[i-1][1] + f[i-1][0])%MOD;
            f[i][1] = (f[i-1][0] + f[i-1][1])%MOD;
        }
    }
    printf("%lld\n",f[n][1]%MOD);
    return 0;
}

T2 摆动数列

首先我通过观察发现 x<y 的和 x>y 的可以分开讨论。

再接着设计一个dp,有点像最长上升子序列有木有?

考虑可以用树状数组维护一个高度的前缀最大值,累加上去。这样就达到了优化dp的效果。

时间复杂度

Talk is cheap.Show me the code.

#include<bits/stdc++.h>
#define int long long
using namespace std;
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^48); ch=getchar(); }
    return x * f;
}
const int N = 4e5+7;
int n,m,cnt;
int X[N],Y[N],b[N];
struct Tree_Data {
    int d[N];
    inline void Add(int x,int y) {
        while(x <= m) {
            d[x] = max(d[x],y); x += x&-x;
        }
    }
    inline int Qmax(int x) {
        int res = 0;
        while(x > 0) {
            res = max(res,d[x]); x -= x&-x;
        }
        return res;
    }
}Tu,Td;
signed main()
{
    //freopen("b.in","r",stdin);
    n = read();
    for(int i=1;i<=n;++i) {
        X[i] = read(), Y[i] = read();
        b[++cnt] = X[i], b[++cnt] = Y[i];
    }
    sort(b+1, b+1+cnt);
    m = unique(b+1, b+1+cnt) - b - 1;
    //printf("must test 'm' = %d\n",m);
    for(int i=1;i<=n;++i) {
        X[i] = lower_bound(b+1, b+1+m, X[i]) - b; Y[i] = lower_bound(b+1, b+1+m, Y[i]) - b;
        //printf("for.%d ,X[i]=%d, Y[i]=%d\n",i,X[i],Y[i]);
        if(X[i] < Y[i]) {
            int now = Tu.Qmax(m-X[i]) + 1; Tu.Add(m-Y[i]+1,now);
        } else {
            int now = Td.Qmax(X[i]-1) + 1; Td.Add(Y[i],now);
        }
    }
    printf("%lld\n",max(Tu.Qmax(m+1),Td.Qmax(m+1)));
    return 0;
}

T3 星球大战

不会。等我变强了再把这题补起来。

全部评论

相关推荐

02-22 21:16
已编辑
门头沟学院 运营
点赞 评论 收藏
分享
会飞的猿:我看你想进大厂,我给你总结一下学习路线吧,java语言方面常规八股要熟,那些java的集合,重点背hashmap八股吧,jvm类加载机制,运行时分区,垃圾回收算法,垃圾回收器CMS、G1这些,各种乐观锁悲观锁,线程安全,threadlocal这些。在进阶一些的比如jvm参数,内存溢出泄漏排查,jvm调优。我这里说的只是冰山一角,详细八股可以去网上找,这不用去买,都免费资源。mysql、redis可以去看小林coding,我看你简历上写了,你一定要熟,什么底层b+树、索引结构、innodb、mvcc、undo log、redo log、行级锁表级锁,这些东西高频出现,如果面试官问我这些我都能笑出来。消息队列rabbitmq也好kafka也好,学一种就行,什么分区啊副本啊确认机制啊怎么保证不重复消费、怎么保证消息不丢失这些基本的一定要会,进阶一点的比如LEO、高水位线、kafka和rocketmq底层零拷贝的区别等等。计算机网络和操作系统既然你是科班应该理解起来问题不大,去看小林coding这两块吧,深度够了。spring boot的八股好好看看吧,一般字节腾讯不这么问,其他的java大厂挺爱问的,什么循环依赖啥的去网上看看。数据结构的话科班应该问题不大,多去力扣集中突击刷题吧。项目的话其实说白了还是结合八股来,想一想你写的这些技术会给你挖什么坑。除此之外,还有场景题、rpc、设计模式、linux命令、ddd等。不会的就别往简历上写了,虽然技术栈很多的话好看些,但背起来确实累。总结一下,多去实习吧,多跳槽,直到跳到一个不错的中厂做跳板,这是一条可行的进大厂的路线。另外,只想找个小厂的工作的话,没必要全都照这些准备,太累了,重点放在框架的使用和一些基础八股吧。大致路线就这样,没啥太多难度,就是量大,你能达到什么高度取决于你对自己多狠,祝好。
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客企业服务