T1

if & else

std

/*
Author:lzx
Blog:https://blog.lzx9.com/
Email:lzx@czoier.top
QQ:2210631299
*/
#include<bits/stdc++.h>
using namespace std;
int x,y;
char o;
int main()
{
    cin>>x>>o>>y;
    if(x+y>=100 || (x/10+y/10)!=(x+y)/10 || o!='+') puts("PR!");
    else cout<<x+y<<"\n";
    return 0;
}

T2

差分

std

/*
Author:lzx
Blog:https://blog.lzx9.com/
Email:lzx@czoier.top
QQ:2210631299
*/
#include<bits/stdc++.h>
using namespace std;
const int MAXN=1e7+10,MX=1e7;
int m,k,s[MAXN];
int main()
{
    cin>>m>>k;
    for(int i=1;i<=m;i++)
    {  
        int a,b;
        cin>>a>>b;
        s[a]++;
        s[b+1]--;
    }
    for(int i=1;i<=MX;i++)
    {
        s[i]+=s[i-1];
    }
    while(k--)
    {
        int x;
        cin>>x;
        cout<<s[x]<<"\n";
    }
    return 0;
}

T3

处理每个点单个长条可覆盖到的最远方格 $a_i$

$$ \color{red}30 pts $$

从每个方格开始,每次用一个长条,重复 $k$ 次

$$ \color{green}100pts $$

依旧从每个方格开始,求用 $k$ 个长条覆盖的最远方格

我们对

求用 $k$ 个长条覆盖的最远方格

的步骤进行优化,比如 $k=5$ 我们可以先用 $2^2$ 个长条,再在用 $2^2$ 个长条覆盖到点最远方格的基础上用 $2^0$ 个长条覆盖,也可以得到

用 $k$ 个长条覆盖的最远方格

我们用 st[i][j] 表示从 $i$ 开始,用 $2^j$ 个长条可以覆盖到的最远方格。

易得:st[i][j]=st[st[i][j-1]][j-1]

边界:st[i][0]=a[i]

std

/*
Author:lzx
Blog:https://blog.lzx9.com/
Email:lzx@czoier.top
QQ:2210631299
*/
#include<bits/stdc++.h>
using namespace std;
const int MAXN=5e5+10;
int n,k,a[MAXN],lg2[MAXN],st[MAXN][32];
int ans;
void STinit()
{
    for(int i=1;i<=lg2[n];i++)
    {
        for(int j=1;j<=n+1;j++)
        {
            st[j][i]=n;
        }
    }
    lg2[1]=0;
    for(int i=2;i<=n;i++)
    {
        lg2[i]=lg2[i>>1]+1;
    }
    for(int i=1;i<=n;i++)
    {
        st[i][0]=a[i];
    }
    for(int i=1;i<=lg2[n];i++)
    {
        for(int j=1;j<=n;j++)
        {
            st[j][i]=st[st[j][i-1]][i-1];
        }
    }
}
int query(int x)
{
    int cnt=k,xx=x;
    while(cnt)
    {
        x=st[x][lg2[cnt]];
        cnt&=((1<<lg2[cnt])-1);
    }
    return x-xx+1;
}
int main()
{
    cin>>n>>k;
    for(int i=1;i<=n;i++)
    {
        a[i]=i;
    }
    for(int i=1;i<=n;i++)
    {
        int x;
        cin>>x;
        a[max(1,i-x)]=max(a[max(1,i-x)],min(n,i+x));
    }
    for(int i=1;i<=n;i++)
    {
        a[i]=max(a[i],a[i-1]);
    }
    STinit();
    for(int i=1;i<=n;i++)
    {
        ans=max(ans,query(i));
    }
    cout<<ans<<"\n";
    return 0;
}

T4

我们可以把这些优先关系看成一个图。比如 $2$ 任务处理完后才能处理 $1$ 任务,就连一条 $2$ 到 $1$ 的有向边。

比如我们构造了如下的一个图:

在此图中,我们观察到 $4,5$ 节点没有前驱任务(即入度为 $0$),这些任务可以优先处理。

于是图就会变成这样:

在这张图中,没有任何一个点可以处理。

因此,我们只要每次把入读为 $0$ 的点移除,知道没有点入读为 $0$。

在这里,我们可以把入读为 $0$ 的数塞入 queue 中,将时间复杂读将为 $\mathcal{O}(n)$。

std

#include<bits/stdc++.h>
using namespace std;
int d[300100];
queue<int> q;
vector<int> a[300100];
bool h[300100];
int main()
{
    int T;
    cin>>T;
    while (T--)
    {
        memset(h,0,sizeof h);
        while (!q.empty())
            q.pop();
        int n;
        cin>>n;
        for (int i=1;i<=n;i++)
            a[i].clear();
        for (int i=1;i<=n;i++)
        {
            cin>>d[i];
            for (int j=1;j<=d[i];j++)
            {
                int x;
                cin>>x;
                a[x].push_back(i);
            }
        }
        for (int i=1;i<=n;i++)
            if (d[i]==0) q.push(i);
        while (!q.empty())
        {
            int x=q.front();
            q.pop();
            h[x]=1;
            for (auto i:a[x])
            {
                d[i]--;
                if (d[i]==0) q.push(i);
            }
        }
        int ans=0;
        for (int i=1;i<=n;i++)
            if (!h[i]) ans++;
        cout<<ans<<endl;
        for (int i=1;i<=n;i++)
            if (!h[i]) cout<<i<<' ';
        if (ans!=0) cout<<endl;
    }
    return 0;
}

T5

std

T6

改编自 CF734E

使用树的直径求解

std

#include <iostream>
#include <vector>
#include <algorithm>

using namespace std;

int n;
vector <int> color;
vector < vector <int> > g;
vector <char> used;
vector <int> comp;
int n1;
vector < vector <int> > g1;
vector <int> dp;
int ans = 0;

void dfs1(int v, int col, int cmp)
{
    if (used[v]) return;
    if (color[v] != col) return;
    used[v] = true;
    comp[v] = cmp;
    for (int i = 0; i < g[v].size(); i++)
    {
        int to = g[v][i];
        dfs1(to, col, cmp);
    }
}

void dfs2(int v, int p = -1)
{
    int mx1 = 0, mx2 = 0;
    for (int i = 0; i < g1[v].size(); i++)
    {
        int to = g1[v][i];
        if (to == p) continue;
        dfs2(to, v);
        int val = dp[to] + 1;
        mx2 = max(mx2, val);
        if (mx1 < mx2) swap(mx1, mx2);
    }
    dp[v] = mx1;
    ans = max(ans, mx1 + mx2);
}

int main()
{
    ios_base::sync_with_stdio(false);
    cin >> n;
    color.resize(n);
    g.resize(n);
    comp.resize(n);
    used.assign(n, false);
    string panrui;
    cin>>panrui;
    for (int i = 0; i < n; i++)
    {
        if(panrui[i]=='G')
        {
            color[i]=1;
        }
        else color[i]=0;
    }
    for (int i = 1; i < n; i++)
    {
        int a, b; cin >> a >> b; a--, b--;
        g[a].push_back(b);
        g[b].push_back(a);
    }
    for (int i = 0; i < n; i++)
        if (!used[i])
            dfs1(i, color[i], n1++);
    g1.resize(n1);
    dp.resize(n1);
    for (int i = 0; i < n; i++)
        for (int j = 0; j < g[i].size(); j++)
        {
            int to = g[i][j];
            if (comp[i] != comp[to])
                g1[comp[i]].push_back(comp[to]);
        }
    dfs2(0);
    cout << (ans + 1) / 2 << endl;
    return 0;
}

最后修改:2023 年 08 月 18 日
如果觉得我的文章对你有用,请随意赞赏