集训总结

集训总结

集训过了得有 34 多了,模拟赛也基本打完了,感觉好像是学了不少,又好像什么也没学,自认为是尽力了吧。

知识点总结:

数据结构:

整体而言,代码能力应该是有所提升的。

  1. 平衡树:

    这应该是我进步的最大的了吧,也在一直调这里的题 虽然都是板子就是了

    基本掌握了单点的 treapfhq_treap,知道了 splay 的原理(虽然还没打过),区间的fhq_treap 正在调,应该可以在回家前完成。

  2. 线段树:

    本来就会,也没啥好说的。

  3. 分块、莫队:

    分块知道思路,也没来的及写题,莫队就是根本就不会了。

  4. 可持久化:

    会思路吧。

DP:

马上要讲,讲完再补吧。

数学:

算是仔细听了一下,虽然是复习,难度还是不低。

竟然是听会了容斥,还是出乎意料的,但只是看了例题,算半会吧,顺带也就半会了二项式反演,做例题的时候感觉挺实用的。

排列组合(和一些定理如 exgcd 、费马小定理)算是简单复习了一下,排列式子还是没背过(不会灵活用

简单听了一下莫比乌斯反演,基本就听懂一个定义和式子(但好像也没什么其他的了),应用还够呛。

欧拉函数(反演)也算是听的听好的了(相较于莫反),应用应该也可以试试,但整体的做题量远不够。

其他的像线性筛之类的倒是差不多 除了线性筛也没有啥了

至于更难的计算几何,就是一点也不会,后面索性就不听了。

其他:

树的重心、直径算是补上了我之前的短板。

数字哈希是学会了,字符串哈希还是差点,没怎么做题。

二分、三分、分治都差不多(好像这种东西还是难在思路,算法很简单),CDQ 套树状数组(或 CDQ 套 CDQ 套 CDQ ……)实在是迷惑,希望可以最少把求解三元逆元学会。

搜索进阶如 A* 等好像还不错(毕竟是第二遍听

题目总结(不保证链接能打开:

  1. 下棋

    真的是不难,单纯是枚举每一个点,在判断是否可以到达这个点,但这个思路实现还值得一看吧(对我来说

    CODE
    #include<bits/stdc++.h>
    using namespace std;
    typedef long long llt;
    const int N=2004;
    #define For(i,a,b,c) for(int $L=a,$R=b,$C=c,$D=(0<=$C)-($C<0),i=$L;i*$D<=$R*$D;i+=$C)
    int n,m;
    char c[N][N];
    bool vis[N][N];
    namespace IO{
    template<typename T> inline void read(T &x){
    char s=getchar();x=0;bool pd=false;
    while(s<'0'||'9'<s){if(s=='-') pd=true;s=getchar();}
    while('0'<=s&&s<='9')x=(x<<1)+(x<<3)+(s^48),s=getchar();
    if(pd) x=-x;
    }
    template<typename T,typename... Args> inline void read(T& x,Args&... args){read(x);read(args...);}
    template<typename T> inline void write(T x){
    static T st[45];T top=0;
    if(x<0)x=~x+1,putchar('-');
    do{st[top++]=x%10;}while(x/=10);
    while(top)putchar(st[--top]^48);
    }
    inline void write(const char c){putchar(c);}
    inline void write(const char *c){
    int len=strlen(c);
    For(i,0,len-1,1) putchar(c[i]);
    }
    template<typename T> inline void Write(T x){write(x);putchar(' ');}
    inline void Write(const char c){write(c);if(c!='\n') putchar(' ');}
    inline void Write(const char *c){write(c),putchar(' ');}
    template<typename T,typename... Args> inline void write(T x,Args... args){write(x);write(args...);}
    template<typename T,typename... Args> inline void Write(T x,Args... args){Write(x);Write(args...);}
    }
    #define read IO::read
    #define write IO::write
    #define Write IO::Write
    int main(){
    #ifndef ONLINE_JUDGE
    freopen("in.in","r",stdin);
    freopen("out.out","w",stdout);
    #endif
    read(n,m);
    memset(c,'z',sizeof c);
    For(i,1,n,1) scanf(" %s",c[i]+1);
    vis[1][0]=vis[0][1]=1;
    For(l,2,n+m-1,1){
    char x='z';
    For(i,1,n,1){
    int j=l-i;
    if(1<=j&&j<=m)
    if(vis[i][j-1]||vis[i-1][j]) x=min(x,c[i][j]);
    }
    putchar(x);
    For(i,1,n,1){
    int j=l-i;
    if(1<=j&&j<=m)
    if((vis[i][j-1]||vis[i-1][j])&&c[i][j]==x)
    vis[i][j]=1;
    }
    }
    putchar(c[n][m]);
    }
  2. 分钱

    一个巧妙 dp ,考虑 dpi,j 表示选前 i 张纸币,差为 j 时的每个人的最大钱数。

    有一个显然转移:

    对于第 k 张纸币,其价值为 ak

    dpi,j=max{dpi1,jdpi1,j+ak+akdpi1,jak+ak

    分别对应的是将第 k 张给多的人,少的人,不给人。

    CODE
    #include<bits/stdc++.h>
    using namespace std;
    typedef long long llt;
    const int N=504,M=1e5+3;
    #define For(i,a,b,c) for(int $L=a,$R=b,$C=c,$D=(0<=$C)-($C<0),i=$L;i*$D<=$R*$D;i+=$C)
    int n,w[N],dp[N][M],sum;
    namespace IO{
    template<typename T> inline void read(T &x){
    char s=getchar();x=0;bool pd=false;
    while(s<'0'||'9'<s){if(s=='-') pd=true;s=getchar();}
    while('0'<=s&&s<='9')x=(x<<1)+(x<<3)+(s^48),s=getchar();
    if(pd) x=-x;
    }
    template<typename T,typename... Args> inline void read(T& x,Args&... args){read(x);read(args...);}
    template<typename T> inline void write(T x){
    static T st[45];T top=0;
    if(x<0)x=~x+1,putchar('-');
    do{st[top++]=x%10;}while(x/=10);
    while(top)putchar(st[--top]^48);
    }
    inline void write(const char c){putchar(c);}
    inline void write(const char *c){
    int len=strlen(c);
    For(i,0,len-1,1) putchar(c[i]);
    }
    template<typename T> inline void Write(T x){write(x);putchar(' ');}
    inline void Write(const char c){write(c);if(c!='\n') putchar(' ');}
    inline void Write(const char *c){write(c),putchar(' ');}
    template<typename T,typename... Args> inline void write(T x,Args... args){write(x);write(args...);}
    template<typename T,typename... Args> inline void Write(T x,Args... args){Write(x);Write(args...);}
    }
    #define read IO::read
    #define write IO::write
    #define Write IO::Write
    int main(){
    #ifndef ONLINE_JUDGE
    freopen("in.in","r",stdin);
    freopen("out.out","w",stdout);
    #endif
    read(n);
    for(int i=1;i<=n;i++) read(w[i]),sum+=w[i];
    memset(dp,-0x7f,sizeof dp);
    dp[0][0]=0;
    for(int i=1;i<=n;i++)
    for(int j=0;j<=sum;j++)
    dp[i][j]=max(dp[i-1][j],max(dp[i-1][abs(j-w[i])],dp[i-1][j+w[i]])+w[i]);
    write(sum-(dp[n][0]/2));
    }
  3. Super_Jaber

    01bfs(好像也有叫其他名字的。

    反正我之前是不会,稍微学了一下。

    用来求解在所有节点编号是 01 的网格图中,所有 01 的最短路径。具体实现就是先将 1 加入队列,然后扩展(类似不用优先队列的 dij。

    这道题还有一个瞬移,转移时加上即可

    CODE
    #include<bits/stdc++.h>
    using namespace std;
    typedef long long llt;
    const int N=1010,K=50;
    #define For(i,a,b,c) for(int $L=a,$R=b,$C=c,$D=(0<=$C)-($C<0),i=$L;i*$D<=$R*$D;i+=$C)
    #define chpt(x,y) (1<=x&&x<=n&&1<=y&&y<=m&&dis[cl][x][y]<0)
    int n,m,k,q,ca[N][N],dis[K][N][N],vis[N];
    struct pt{int x,y;}que[N];
    vector<pt> cc[K];
    namespace IO{
    template<typename T> inline void read(T &x){
    char s=getchar();x=0;bool pd=false;
    while(s<'0'||'9'<s){if(s=='-') pd=true;s=getchar();}
    while('0'<=s&&s<='9')x=(x<<1)+(x<<3)+(s^48),s=getchar();
    if(pd) x=-x;
    }
    template<typename T,typename... Args> inline void read(T& x,Args&... args){read(x);read(args...);}
    template<typename T> inline void write(T x){
    static T st[45];T top=0;
    if(x<0)x=~x+1,putchar('-');
    do{st[top++]=x%10;}while(x/=10);
    while(top)putchar(st[--top]^48);
    }
    inline void write(const char c){putchar(c);}
    inline void write(const char *c){
    int len=strlen(c);
    For(i,0,len-1,1) putchar(c[i]);
    }
    template<typename T> inline void Write(T x){write(x);putchar(' ');}
    inline void Write(const char c){write(c);if(c!='\n') putchar(' ');}
    inline void Write(const char *c){write(c),putchar(' ');}
    template<typename T,typename... Args> inline void write(T x,Args... args){write(x);write(args...);}
    template<typename T,typename... Args> inline void Write(T x,Args... args){Write(x);Write(args...);}
    }
    #define read IO::read
    #define write IO::write
    #define Write IO::Write
    int main(){
    #ifndef ONLINE_JUDGE
    freopen("in.in","r",stdin);
    freopen("out.out","w",stdout);
    #endif
    memset(dis,-1,sizeof dis);
    read(n,m,k);
    For(i,1,n,1) For(j,1,m,1) read(ca[i][j]),cc[ca[i][j]].push_back({i,j});
    For(cl,1,k,1){
    queue<pt> que;
    for(pt i:cc[cl]) que.push(i),dis[cl][i.x][i.y]=0;
    while(!que.empty()){
    int x=que.front().x,y=que.front().y;que.pop();
    int col=ca[x][y],cld=dis[cl][x][y];
    if(chpt(x+1,y)) dis[cl][x+1][y]=dis[cl][x][y]+1,que.push({x+1,y});//转移移动
    if(chpt(x-1,y)) dis[cl][x-1][y]=dis[cl][x][y]+1,que.push({x-1,y});
    if(chpt(x,y+1)) dis[cl][x][y+1]=dis[cl][x][y]+1,que.push({x,y+1});
    if(chpt(x,y-1)) dis[cl][x][y-1]=dis[cl][x][y]+1,que.push({x,y-1});
    if(vis[col]!=cl){
    vis[col]=cl;
    for(pt i:cc[col])
    if(dis[cl][i.x][i.y]<0) dis[cl][i.x][i.y]=cld+1,que.push({i.x,i.y});//转移颜色
    }
    }
    }
    read(q);
    For(i,1,q,1){
    int ax,ay,bx,by;read(ax,ay,bx,by);
    int mi=abs(ax-bx)+abs(ay-by);
    For(j,1,k,1) mi=min(mi,dis[j][ax][ay]+dis[j][bx][by]+1);
    write(mi,'\n');
    }
    }
  4. 糖果

    考虑一个如果存在一个合法分法,一定可以将其分成 2,3 组(因为每个异或和一样的 3 组就可以合并成一组。

    对于 2 组,直接全局前缀异或和为 0

    对于 3 组,可以枚举前缀,在在后缀中查找是否相等,在判一下全部的异或和是否相等,

  5. 魔法仪式

    经典区间分治。

    考虑将中点左右分治后合并。

    将最大值在左右两边分别考虑。

    有中点到左边枚举点作为最大的值,指针右边的可取范围(类似双指针),在同时维护 sumx 表示到右边指针范围内 和 modk=x 的个数。

    右边同理维护。

其他想说的:

写这个的初心是模拟赛打的太寄了,想着先把东西总结一下在学新的。

accoders 上的题还是挺好的(都不会。

真说收获,也不少了,也感受到了自己的成长和不足。

应该还会补吧。

posted @   5k_sync_closer  阅读(36)  评论(0编辑  收藏  举报
编辑推荐:
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· 没有源码,如何修改代码逻辑?
阅读排行:
· 分享4款.NET开源、免费、实用的商城系统
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
点击右上角即可分享
微信分享提示