首页 > 其他分享 >2022icpc网络赛

2022icpc网络赛

时间:2022-10-03 10:55:56浏览次数:52  
标签:pp int res 网络 cin yy xx 2022icpc

E An Interesting Sequence

题意:

请构造一个总和最小,长度为n且首项为k,并且相邻两项的gcd = 1的数组,输出数组各项之和。

分析:

显然对于n的奇数和偶数我们要进行分类讨论,我们希望数组的和更小,并且gcd = 1,那么我们只需要在数组中添加2和3即可。

不管什么情况,数组的第二位我们一定要找到第一个不能整除k的质数,所以我们筛完质数再找到这个值。

然后奇偶位子上都放2 3 2 3即可,特盘奇数情况是不是非要先放3即可。

void init() {
    for(int i = 2 ; i < N ; i ++ ) {
        if(!st[i]) primes[cnt ++ ] = i;
        for(int j = 0 ; primes[j] * i < N ; j ++ ) {
            st[primes[j] * i] = true;
            if(i % primes[j] == 0) break;
        }
    }
}

signed main() {
    init();
    cin >> n >> k;
    int t = 0; 
    for(int i = 0 ; i < cnt; i ++ ) {
        int p = primes[i];
        if(k % p) {
            t = p;
            break;
        }
    }
    
    if(n & 1) {
        cout << n / 2 * 5 - 5 + k + t + (t % 2 == 0) + 2 << endl;
    }
    else {
        cout << n / 2 * 5 - 5 + k + t << endl;
    }
}

F Infinity Tree

题意:

现在给出<u,v> 求出LCA(u,v)

分析:

首先我们可以知道每个时刻的节点数 i 时刻 节点就有 pow[(1+k),i-1]

可以预处理每个时间的节点个数 p[i]

接下来就是找父亲 因为深度不会很深 所以直接暴力找即可

怎么找一个点的父亲 ? 肯定是能够计算出来的

我们可以通过上一个时间节点个数p[i-1] 【即小于当前节点的最近的时间节点数】和当前节点算出父亲节点

最后<u,v>谁的节点大 就往上跳 直到节点重合

void solve() {
    int k, x, y;
    cin >> k >> x >> y;
    
    __int128 xx = 1;
    for(xx = 1 ; xx < x ; xx *= (k + 1)); 
    __int128 yy = 1;
    for(yy = 1 ; yy < y ; yy *= (k + 1));
    xx /= (k + 1), yy /= (k + 1);

    while(x != y) {
        if(x > y) {
            x = (x - xx + k - 1) / k;
            for(xx = 1 ; xx < x ; xx *= (k + 1));
            xx /= (k + 1);
        }
        if(x < y) {
            y = (y - yy + k - 1) / k;
            for(yy = 1 ; yy < y ; yy *= (k + 1));
            yy /= (k + 1);
        }
    }
    cout << x << endl;
}

J A Game about Increasing Sequences

题意:

Alice,Bob在一个数组上玩游戏。

二人轮流取走头部或者尾部的一个数,每次取的数要严格大于之前取的全部的数。

无法取到的算输。

分析:

考虑两端开始的最长连续上升序列分别为x和y

若x和y都为偶数,那么先手必输,因为不管先手取哪一端的,后手都可以取先手同一端的数字。

若x和y都为奇数,那么先手必赢,因为只要先手取较大的一端开始,之后只能取这一段的数字,先手必赢

若x和y中有一个为奇数,那么先手也必赢,因为只要先手取为奇数的那端开始,之后就是两端为偶数的必败局面,先手必赢

void solve(){
    cin>>n;
    F(i,1,n) cin>>a[i];
    int x=1;
    dF(i,n-1,1){
        if(a[i]>a[i+1]) x++;
        else break;
    }
    int y=1;
    F(i,2,n){
        if(a[i]>a[i-1]) y++;
        else break;
    }
    if(x&1||y&1) cout<<"Alice\n";
    else cout<<"Bob\n";
}

B Non-decreasing Array

分析

int f[N][N]; // 第i位 删除j次 但是保留i位置 的最大值
int calc(int l, int r) {
    return (a[r] - a[l]) * (a[r] - a[l]);
}

signed main() {
    cin >> n;
    for(int i = 1; i <= n ; i ++ ) cin >> a[i];
    for(int i = 1 ; i <= n ; i ++ ) 
        for(int j = 0 ; j <= i - 2 ; j ++ ) 
            for(int k = 0 ; k <= j ; k ++ ) {
                int pos = i - k - 1; // 删除[pos + 1, i - 1]的区间:[i - k + 1, i - 1] // k是长度
                f[i][j] = max(f[i][j], f[pos][j - k] + calc(pos, i));
            }

    for(int i = 1 ; i <= n ; i ++ ) {
        if(i * 2 > n - 2) cout << f[n][n - 2] << endl;
        else cout << f[n][2 * i] << endl;
    }
    return 0;
}

G Good Permutation

ll fac[N];
vector<int>st[N],ed[N],g[N];
int len[N];
ll dfs(int u) {
    ll res = 1;
    int s = 0;
    for (int v : g[u]) {
        res *= dfs(v);
        s += len[v];
        res %= mod;
    }
    res *= fac[len[u] - s + g[u].size()];
    res %= mod;
    return res;
}

void slove() {
    fac[0] = 1;
    for (int i = 1; i <= 1000005; i++) {
        fac[i] = i * fac[i - 1] % mod;
    }
    cin >> n >> m;
    vector<pair<int, int>>pp;
    pp.push_back({ 0,0 });
    for (int i = 1; i <= m; i++) {
        int l, r; cin >> l >> r;
        pp.push_back({ l,r });
    }
    sort(pp.begin(), pp.end());
    for (int i = 1; i < pp.size(); i++) {
        if (pp[i] != pp[i - 1]) {
            int L = pp[i].first, R = pp[i].second;
            len[i] = R - L + 1;
            st[L].push_back(i);
            ed[R].push_back(i);
        }
    }
    for (int i = 1; i <= n; i++) {
        sort(st[i].begin(), st[i].end(), [](int a, int b) {return len[a] > len[b]; });
        sort(ed[i].begin(), ed[i].end(), [](int a, int b) {return len[a] < len[b]; });
    }
    stack<int>stk; stk.push(0);
    for (int i = 1; i <= n; i++) {
        for (int x : st[i]) {
            stk.push(x);
        }
        for (int x : ed[i]) {
            if (x == stk.top()) {
                stk.pop();
                int fa = stk.top();
                g[fa].push_back(x);
            }
        }
    }
    len[0] = n;
    cout << dfs(0) << endl;
}

L Quadruple

题意:

q次询问,每次询问给出l,r.计算出s[l~r]中为"icpc"的字串数量

分析

考虑用前缀和 s[i] 表示前i个中icpc的个数为多少个

但是答案 只是 s[r]-s[l-1] 肯定是不够的

还要

减去 [1,l-1]中 i 的个数×[l,r]中cpc的个数

减去[1,l-1]中ic的个数×[l,r]中pc的个数

减去[1,l-1]中icp的个数×[l,r]中c的个数

发现有很多子问题 只要一直划分就好

代码是未取模版本

int ICPC[N], ICP[N], CPC[N];
int IC[N], CP[N], PC[N];
int I[N], C[N], P[N];
int x, a, b, p;
struct Node {
    int l, r;
} q[N];

int PC_sum(int l, int r) {
    return PC[r] - PC[l - 1] - P[l - 1] * (C[r] - C[l - 1]);
}

int CPC_sum(int l, int r) {
    return CPC[r] - CPC[l - 1] 
                  - C[l - 1] * PC_sum(l, r)
                  - CP[l - 1] * (C[r] - C[l - 1]);
}

signed main()
{
    cin >> n >> m;
    cin >> s;
    s = "?" + s;
    cin >> x >> a >> b >> p;
    for(int i = 1; i <= n ; i ++ ) 
    {
        // 继承
        I[i] = I[i - 1], C[i] = C[i - 1], P[i] = P[i - 1];
        IC[i] = IC[i - 1], CP[i] = CP[i - 1], PC[i] = PC[i - 1];
        ICPC[i] = ICPC[i - 1], ICP[i] = ICP[i - 1], CPC[i] = CPC[i - 1];
        
        if(s[i] == 'I') {
            I[i] ++ ;
        }
        else if(s[i] == 'C') {
            C[i] ++ ;
            IC[i] += I[i - 1];
            PC[i] += P[i - 1];
            CPC[i] += CP[i - 1];
            ICPC[i] += ICP[i - 1];
        }
        else if(s[i] == 'P') {
            P[i] ++ ;
            CP[i] += C[i - 1];
            ICP[i] += IC[i - 1];
        }
    }
    
    // 预处理询问
    for(int i = 1; i <= m ; i ++ ) {
        x = (a * x + b) % p;
        q[i].l = x % n + 1;
    }
    for(int i = 1; i <= m ; i ++ ) {
        x = (a * x + b) % p;
        q[i].r = x % n + 1;
    }
    
    int ans = 0;
    for(int i = 1; i <= m; i ++ ) {
        auto [l, r] = q[i];
        if(l > r) swap(l, r);
        int res = ICPC[r] - ICPC[l - 1]
                - I[l - 1] * CPC_sum(l, r) 
                - IC[l - 1] * PC_sum(l, r)
                - ICP[l - 1] * (C[r] - C[l - 1]);
        ans = (ans + res) % mod;
    }
    cout << ans << endl;
    return 0;
}

标签:pp,int,res,网络,cin,yy,xx,2022icpc
From: https://www.cnblogs.com/wzxbeliever/p/16750143.html

相关文章

  • 13第十二章:Docker网络
    一、Docker平台架构图解1、整体说明从其架构和运行流程来看,Docker是一个C/S模式的架构,后端是一个松耦合架构,众多模块各司其职。Docker运行的基本流程为:用户是使......
  • java网络编程--1 网络模型、网络协议
    java网络编程--1网络模型、网络协议javaweb指的是网页编程B/S网络编程指的是面向TCP/IP相关C/S1.1、概述两种不同的通信模式:实时通信:打电话连接---接了--......
  • 网络安全中常用浏览器插件、拓展
    引言现在的火狐、Edge( Chromium内核)、Chrome等浏览器带有插件、拓展(Plugin)的功能。这些插件中有的可以过滤广告,有的提供便捷的翻译,有的提供JavaScript脚本支持,方便用户的......
  • 计算机网络原理(三):运输层
    运输层服务多路复用与多路分解无连接运输:UDP可靠数据传输原理面向连接的运输:TCP拥塞控制原理及TCP拥塞控制 一、运输层服务1.1运输层服务运输层协议为运行在不......
  • 【Swoole系列6.3】Hyperf 运行各种网络服务
    Hyperf运行各种网络服务简单地运行起普通的HTTP服务之后,今天我们再来学习一下如何使用Hyperf运行TCP/UDP以及WebSocket服务。之前我们通过普通的Swoole都已经搭......
  • 计算机网络_1
    ·第一章:概论~互联网-网络节点和边-计算机网络节点(主机节点,即数据的源或目标;数据交换节点,即数据的中转节点)、边(数据链路,包括接入链路和骨干链路)和协议-互联网(Interne......
  • 深度和广度优先搜索:如何找出社交网络中的三度好友关系?
    地址:https://time.geekbang.org/column/article/70891目录什么是“搜索”算法?深度优先搜索(DFS)广度优先搜索(BFS)内容小结什么是“搜索”算法?算法是作用于具体数据结构之上......
  • 网络字节序与主机字节序的转换
    字节序概念字节序即字节的顺序,指多字节数据在计算机内存中存储或网络传输时个字节的存储顺序(从先至后、从后至先)。分类字节序的常见序分为大端字节序(B......
  • 网络字节序与主机字节序的转换实践
    问:字节序是什么?答:指字节在内存中存储的顺序。比如一个int32_t类型的数值占用4个字节,这4个字节在内存中的排列顺序就是字节序。字节序有两种:(1)小端字节序(Littleendinan),数......
  • 网络中冗余备份
    冗余备份的重要性如今社会,网络是各个产业的新的血脉,网络的稳定性至关重要,一旦网络出现故障,导致断网、延迟丢包等很可能会导致生产作业停滞,造成较经济损失,为此冗余备份至......