ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

《2022牛客寒假算法基础集训营3》

2022-01-30 09:02:05  阅读:137  来源: 互联网

标签:rt vis int 牛客 sons 2022 ans 集训营 dp


C:首先我们可以知道重量为1的方案数就是重量为2的物品的数量,因为只有2 / 2 = 1可以影响它。

那么如果我们从小到大迭代的话,对于当前位置i,只能赋值2 * i才能影响当前位置,那么如果当前方案数的差为d,那么就还需要放d个2 * i。

这里要注意的是差值可能为负数。

#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
typedef pair<int,int> pii;
const int N = 1e3 + 5;
const int M = 1e7 + 5;
const LL Mod = 1e9 + 7;
#define rep(at,am,as) for(int at = am;at <= as;++at)
#define INF 1e14
#define dbg(ax) cout << "now this num is " << ax << endl;
inline long long ADD(long long x,long long y) {
    if(x + y < 0) return ((x + y) % Mod + Mod) % Mod;
    return (x + y) % Mod;
}
inline long long MUL(long long x,long long y) {
    if(x * y < 0) return ((x * y) % Mod + Mod) % Mod;
    return x * y % Mod;
}
inline long long DEC(long long x,long long y) {
    if(x - y < 0) return (x - y + Mod) % Mod;
    return (x - y) % Mod;
}

int m;
LL a[N],dp[N];
vector<int> ans;
void solve() {
    cin >> m;
    rep(i,1,m) cin >> a[i];
    rep(i,1,m) {
        int d = ((a[i] - dp[i]) % Mod + Mod) % Mod;
        //while(((a[i] - dp[i]) % Mod + Mod) % Mod != 0) {
        rep(j,1,d) {
            int w = i * 2;
            ans.push_back(w);
            for(int j = m;j >= 1;--j) {
                if(j - w >= 0) dp[j] = ADD(dp[j],dp[j - w]);
                if(j - w / 2 >= 0) dp[j] = ADD(dp[j],dp[j - w / 2]);
            }
            if(w < N) dp[w] = ADD(dp[w],1);
            dp[w / 2] = ADD(dp[w / 2],1);
        }
        //}
    }
    if(ans.size() == 0) ans.push_back(2 * 1000);
    printf("%d\n",ans.size());
    for(auto v : ans) printf("%d ",v);
}   
int main() {
    // int _;
    // for(scanf("%d",&_);_;_--) {
        solve();
    //}
    //system("pause");
    return 0;
}
View Code

H:首先,选定一个点作为轴,那么它就旋转到了父节点处。

那么对于一棵子树,我们要把他的原来的根旋转上来,我们就只需要一直选定原来的根作为轴即可。

旋转的操作就是Splay就行了。

#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
typedef pair<int,int> pii;
const int N = 1e3 + 5;
const int M = 1e7 + 5;
const LL Mod = 998244353;
#define rep(at,am,as) for(int at = am;at <= as;++at)
#define INF 1e14
#define dbg(ax) cout << "now this num is " << ax << endl;
inline long long ADD(long long x,long long y) {
    if(x + y < 0) return ((x + y) % Mod + Mod) % Mod;
    return (x + y) % Mod;
}
inline long long MUL(long long x,long long y) {
    if(x * y < 0) return ((x * y) % Mod + Mod) % Mod;
    return x * y % Mod;
}
inline long long DEC(long long x,long long y) {
    if(x - y < 0) return (x - y + Mod) % Mod;
    return (x - y) % Mod;
}

int n;
vector<int> ans;
struct Splay {
    int sons[N][2],f[N],rt;
    bool vis[N];
    inline void Input() {
        rep(i,1,n) scanf("%d %d",&sons[i][0],&sons[i][1]),f[sons[i][0]] = f[sons[i][1]] = i,vis[sons[i][0]] = vis[sons[i][1]] = 1;
        rep(i,1,n) if(!vis[i]) rt = i;
        memset(vis,0,sizeof(vis));
    }
    inline bool chk(int x) {return sons[f[x]][1] == x;}
    inline void rotate(int x) {
        ans.push_back(x);
        int y = f[x], z = f[y], k = chk(x), w = sons[x][k^1];
        sons[y][k] = w;f[w] = y;
        sons[z][chk(y)] = x; f[x] = z;
        sons[x][k^1] = y; f[y] = x;
    }
    inline void splay(int x,int goal = 0) {
        while(!vis[f[x]] && f[x] != goal) {
            int y = f[x],z = f[y];
            if(!vis[z] && z != goal) {
                if (chk(x) == chk(y)) rotate(y);
                else rotate(x);
            }
            rotate(x);
        }
    }
}A,B;
void dfs(int rt) {
    B.splay(rt);
    B.vis[rt] = 1;
    if(A.sons[rt][0]) dfs(A.sons[rt][0]);
    if(A.sons[rt][1]) dfs(A.sons[rt][1]);
}
void solve() {
    scanf("%d",&n);
    A.Input();
    B.Input();
    dfs(A.rt);
    printf("%d\n",ans.size());
    for(auto v : ans) printf("%d\n",v);

}   
int main() {
    // int _;
    // for(scanf("%d",&_);_;_--) {
        solve();
    //}
    //system("pause");
    return 0;
}
View Code

 J:这题挺不错的。

首先我们把[L,R]都转到[0,R]上做处理。

那么就是说对于[0,R]上的点 % P之后在[l,r]里的数量。

那么就分为了k段的[0,P - 1]还有一段多出来的即R % P。

这里我们用线段合并

 

标签:rt,vis,int,牛客,sons,2022,ans,集训营,dp
来源: https://www.cnblogs.com/zwjzwj/p/15856319.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有