Wannafly挑战赛14

链接:https://www.nowcoder.com/acm/contest/81/A
来源:牛客网

直角三棱锥
时间限制:C/C++ 1秒,其他语言2秒
空间限制:C/C++ 262144K,其他语言524288K
64bit IO Format: %lld

题目描述

在三维空间中,平面 x = 0, y = 0, z = 0,以及平面 x + y + z = K 围成了一个三棱锥。
整天与整数打交道的小明希望知道这个三棱锥内、上整点的数目。
他觉得数量可能很多,所以答案需要对给定的 M 取模。

输入描述:

输入有 1 ≤ T ≤ 10
5
 组数据。
每组数据中,输入两个整数 0 ≤ K ≤ 10
9
 + 7, 1 ≤ M ≤ 10
9
 + 7,意义如题目描述。

输出描述:

对于每组数据,输出一个整数,为三棱锥内、上整点的数目对 M 取模。
示例1

输入

4
0 60
1 60
29 60
29 100007

输出

1
4
40
4960

 求 x + y + z< = K的个数

可以用隔板法啊,先选一个,再插入一个,再插入一个,但是是直角锥,所以只有一个符合

#include <bits/stdc++.h>
using namespace std;
int main()
{
    int t;
    cin>>t;
    while(t--)
    {
        int n,m;
        cin>>n>>m;
        __int128 t=1;
        cout<<(int)(t*(n+1)*(n+2)*(n+3)/6%m)<<"
";
    }
}

 链接:https://www.nowcoder.com/acm/contest/81/C
来源:牛客网

可达性
时间限制:C/C++ 1秒,其他语言2秒
空间限制:C/C++ 262144K,其他语言524288K
64bit IO Format: %lld

题目描述

给出一个 0 ≤ N ≤ 105 点数、0 ≤ M ≤ 105 边数的有向图,
输出一个尽可能小的点集,使得从这些点出发能够到达任意一点,如果有多个这样的集合,输出这些集合升序排序后字典序最小的。

输入描述:

第一行为两个整数 1 ≤ n, m ≤ 10
5

接下来 M 行,每行两个整数 1 ≤ u, v ≤ 10
5
 表示从点 u 至点 v 有一条有向边。
数据保证没有重边、自环。

输出描述:

第一行输出一个整数 z,表示作为答案的点集的大小;
第二行输出 z 个整数,升序排序,表示作为答案的点集。
示例1

输入

7 10
4 5
5 1
2 5
6 5
7 2
4 2
1 2
5 3
3 5
3 6

输出

2
4 7

tarjan模板题,先求强连通分量,然后缩点

#include<bits/stdc++.h>
using namespace std;
const int N=1e5+5;
vector<int>G[N],id[N];
int low[N],dfn[N],instack[N],st[N],tot,cnt,scc,p;
int belong[N],in[N];
void tarjan(int u)
{
    int v;
    low[u]=dfn[u]=++tot;//时间戳
    st[++cnt]=u;//入栈
    instack[u]=1;
    for(int i=0;i<G[u].size();i++)
    {
        v=G[u][i];
        if(!dfn[v])//是否已经访问
        {
            tarjan(v);
            low[u]=min(low[u],low[v]);
        }
        else if(instack[v])//已经访问过并且在栈里
        {
            low[u]=min(low[u],dfn[v]);
        }
    }
    if(low[u]==dfn[u])
    {
        scc++;//强连通
        do{
            v=st[cnt--];//出栈
            instack[v]=0;//v出栈后
            belong[v]=scc;//v属于哪个强连通1-scc
            id[scc].push_back(v);//当前强连通的子集
        }while(u!=v);
    }
}
int main()
{
    int n,m,u[N],v[N];
    scanf("%d%d",&n,&m);
    for(int i=1;i<=m;i++)
    {
        scanf("%d%d",&u[i],&v[i]);
        G[u[i]].push_back(v[i]);
    }
    for(int i=1;i<=n;i++)//求所有强连通
        if(!dfn[i])//是否已经访问过
            tarjan(i);
    for(int i=1;i<=m;i++)//缩点,因为强连通分量中的每两个点都是强连通的,可以将一个强连通分量当做一个超级点
    {
        if(belong[u[i]]==belong[v[i]])continue;
        in[belong[v[i]]]++;
    }
    vector<int> res;
    for(int i=1;i<=scc;i++)
        if(!in[i])res.push_back(*min_element(id[i].begin(),id[i].end()));
    printf("%d
%d",res.size(),res[0]);
    for(int i=1;i<res.size();i++)
        printf(" %d",res[i]);
    return 0;
}
原文地址:https://www.cnblogs.com/BobHuang/p/8901164.html