《农林大学校赛补题》

M:一开始想的bfs松弛dp,但是T了。

然后想的是去枚举全部的高度,然后bfs判断,显然这也会T。

但是可以发现的是,其实我们只需要找到最大的能承受的高度即可。

所以就可以二分了。

#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
typedef pair<int,int> pii;
const int N = 1e5+5;
const int M = 1e6+5;
const LL Mod = 9999999967;
#define pi acos(-1)
#define INF 1e18
#define CT0 cin.tie(0),cout.tie(0)
#define IO ios::sync_with_stdio(false)
#define dbg(ax) cout << "now this num is " << ax << endl;
namespace FASTIO{
    inline LL read()
    {
        LL x = 0,f = 1;char c = getchar();
        while(c < '0' || c > '9'){if(c == '-')f = -1;c = getchar();}
        while(c >= '0' && c <= '9'){x = (x << 1) + (x << 3) + (c ^ 48);c = getchar();}
        return x * f;
    }
    void print(int x){
        if(x < 0){x = -x;putchar('-');}
        if(x > 9) print(x/10);
        putchar(x%10+'0');
    }
}
using namespace FASTIO;

int a[1005][1005],b[4][2] = {1,0,-1,0,0,1,0,-1},n;
int vis[1005][1005];
bool bfs(int dis)
{
    memset(vis,0,sizeof(vis));
    queue<pii> Q;
    Q.push(pii{1,1});
    vis[1][1] = 1;
    if(a[1][1] < dis) return false;
    while(!Q.empty())
    {
        int x = Q.front().first;
        int y = Q.front().second;
        Q.pop();
        if(x == n && y == n) return true;
        for(int i = 0;i < 4;++i)
        {
            int px = x + b[i][0];
            int py = y + b[i][1];
            if(px >= 1 && px <= n && py >= 1 && py <= n && !vis[px][py] && a[px][py] >= dis)
            {
                vis[px][py] = 1;
                Q.push(pii{px,py});
            }
        }
    }
    return false;
}
int main()
{
    n = read();
    for(int i = 1;i <= n;++i)
        for(int j = 1;j <= n;++j) a[i][j] = read();
    int L = 1,r = 100000,ans;
    while(L <= r)
    {
        int mid = (L + r) >> 1;
        if(bfs(mid))
        {
            ans = mid;
            L = mid +1;
        }
        else r =  mid - 1;
    }
    int q;q = read();
    while(q--)
    {
        int x;x = read();
        printf("%s
",x <= ans ? "Wuhu" : "Hmmm");
    }
    system("pause");
    return 0;
}
View Code

 F:大意了,这里模数很大,会爆longlong。所以上int128

#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
typedef pair<double,int> pii;
const int N = 1e8+5;
const int M = 1e6+5;
const LL Mod = 9999999967;
#define rg register
#define pi acos(-1)
#define INF 1e18
#define CT0 cin.tie(0),cout.tie(0)
#define IO ios::sync_with_stdio(false)
#define dbg(ax) cout << "now this num is " << ax << endl;
namespace FASTIO{
    inline LL read()
    {
        LL x = 0,f = 1;char c = getchar();
        while(c < '0' || c > '9'){if(c == '-')f = -1;c = getchar();}
        while(c >= '0' && c <= '9'){x = (x << 1) + (x << 3) + (c ^ 48);c = getchar();}
        return x * f;
    }
    void print(int x){
        if(x < 0){x = -x;putchar('-');}
        if(x > 9) print(x/10);
        putchar(x%10+'0');
    }
}
using namespace FASTIO;

__int128_t quick_mi(__int128_t a,__int128_t b)
{
    __int128_t re = 1;
    a %= Mod;
    while(b)
    {
        if(b&1) re = (re * a) % Mod;
        a = (a * a) % Mod;
        b >>= 1;
    }
    return re;
}
int main()
{
    int ca;ca = read();
    while(ca--)
    {
        LL x,i;x = read(),i = read();
        LL ans = (LL)quick_mi((__int128_t)x,(__int128_t)i);
        printf("%lld
",ans);
    }
    system("pause");
    return 0;
}
View Code

 J:dsu on tree,比赛的时候想到了,但是中间没处理好。

不过我的思路还是对的。

先算贡献,再去加入子树的点值。

但是这里由于对于u这个节点,首先算贡献的时候不能算入,然后加边的时候又要算入。

所以我们solve的时候直接对一个个子节点遍历去计算,主要u这个点的贡献一定要加上。

#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
typedef pair<double,int> pii;
const int N = 1e5+5;
const int M = 1e6+5;
const LL Mod = 9999999967;
#define rg register
#define pi acos(-1)
#define INF 1e18
#define CT0 cin.tie(0),cout.tie(0)
#define IO ios::sync_with_stdio(false)
#define dbg(ax) cout << "now this num is " << ax << endl;
namespace FASTIO{
    inline LL read()
    {
        LL x = 0,f = 1;char c = getchar();
        while(c < '0' || c > '9'){if(c == '-')f = -1;c = getchar();}
        while(c >= '0' && c <= '9'){x = (x << 1) + (x << 3) + (c ^ 48);c = getchar();}
        return x * f;
    }
    void print(int x){
        if(x < 0){x = -x;putchar('-');}
        if(x > 9) print(x/10);
        putchar(x%10+'0');
    }
}
using namespace FASTIO;

int n,val[N],ssize[N],son[N],Son = 0;
LL ans = 0;
vector<int> G[N];
unordered_map<int,int> mp;
void dfs(int u,int fa)
{
    ssize[u] = 1;
    for(auto v : G[u])
    {
        if(v == fa) continue;
        dfs(v,u);
        ssize[u] += ssize[v];
        if(ssize[v] > ssize[son[u]]) son[u] = v;
    }
}
void solve(int u,int fa,int top)
{
    ans += mp[2 * val[top] - val[u]];
    for(auto v : G[u])
    {
        if(v == fa || v == Son) continue;
        solve(v,u,top);
    }
}
void add(int u,int fa,int num)
{
    mp[val[u]] += num;
    for(auto v : G[u])
    {
        if(v == fa || v == Son) continue;
        add(v,u,num);
    }
}
void dfs1(int u,int fa,int opt)
{
    for(auto v : G[u])
    {
        if(v == fa || v == son[u]) continue;
        dfs1(v,u,0);
    }
    if(son[u]) dfs1(son[u],u,1),Son = son[u];
    for(auto v : G[u])
    {
        if(v == fa || v == son[u]) continue;
        solve(v,u,u);
        add(v,u,1);
    }
    mp[val[u]]++;
    Son = 0;
    if(opt == 0) add(u,fa,-1);
}
int main()
{
    n = read();
    for(int i = 1;i <= n;++i) val[i] = read();
    for(int i = 1;i < n;++i)
    {
        int x,y;x = read(),y = read();
        G[x].push_back(y);
        G[y].push_back(x);
    }
    dfs(1,0);
    dfs1(1,0,0);
    printf("%lld
",ans * 2);
    system("pause");
    return 0;
}
View Code

 A:首先,除法可以满足分子分母取模后依旧成立的性质。

那么我们处理出所有x值然后做一次逆元即可。

但是这题就是卡了内存,1e8的空间开不出来。

但是仔细看我们最多只需要处理2e5的数据,所以map来记录下即可。

#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
typedef pair<int,int> pii;
const int N = 1e5+5;
const int M = 1e6+5;
const LL Mod = 1e9+7;
#define pi acos(-1)
#define INF 1e18
#define CT0 cin.tie(0),cout.tie(0)
#define IO ios::sync_with_stdio(false)
#define dbg(ax) cout << "now this num is " << ax << endl;
namespace FASTIO{
    inline int read()
    {
        int x = 0,f = 1;char c = getchar();
        while(c < '0' || c > '9'){if(c == '-')f = -1;c = getchar();}
        while(c >= '0' && c <= '9'){x = (x << 1) + (x << 3) + (c ^ 48);c = getchar();}
        return x * f;
    }
    void print(int x){
        if(x < 0){x = -x;putchar('-');}
        if(x > 9) print(x/10);
        putchar(x%10+'0');
    }
}
using namespace FASTIO;

LL quick_mi(LL a,LL b)
{
    LL re = 1;
    a %= Mod;
    while(b)
    {
        if(b&1) re = (re * a) % Mod;
        a = (a * a) % Mod;
        b >>= 1;
    }
    return re;
}
pii a[N];
int b[N << 1],tot = 0;
map<int,int> mp;
int main()
{
    int n;n = read();
    for(int i = 1;i <= n;++i) a[i].first = read(),a[i].second = read(),b[++tot] = a[i].first,b[++tot] = a[i].second;
    sort(b + 1,b + tot + 1);
    int L = 0;
    LL x = 1;
    mp[0] = 1;
    for(int i = 1;i <= tot;++i)
    {
        while(L < b[i]) x = x * (x + 1) % Mod,L++;
        mp[b[i]] = x;
    }
    for(int i = 1;i <= n;++i)
    {
        if(a[i].first < a[i].second) swap(a[i].first,a[i].second);
        LL ans = mp[a[i].first] * quick_mi(mp[a[i].second],Mod - 2) % Mod;
        printf("%lld
",ans);
    }
    system("pause");
    return 0;
}
View Code
原文地址:https://www.cnblogs.com/zwjzwj/p/13871209.html