day1——2020牛客暑期多校训练营

J   Easy Integration

高数题

光看题目解释没想到怎么去下手,看了别人的解析发现还是自己数论部分的题目刷太少导致经验不足,从而没思路去做这种题。

依次类推得到:

对于取模后要进行相除的数一般都化成逆元处理。

#include <bits/stdc++.h>
#define debug freopen("r.txt","r",stdin)
#define mp make_pair
#define ri register int
using namespace std;
typedef long long ll;
typedef pair<int, int> pii;
const int maxn = 2e6+10;
const int INF = 0x3f3f3f3f; 
const int mod = 998244353;
inline ll read(){ll s=0,w=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')w=-1;ch=getchar();}
while(ch>='0'&&ch<='9') s=s*10+ch-'0',ch=getchar();
return s*w;}
ll qpow(ll p,ll q){return (q&1?p:1)*(q?qpow(p*p%mod,q/2):1)%mod;}
ll a[maxn];
int i,n;
int main()
{
    a[0]=1;
    for (i=1;i<=maxn;i++) a[i]=a[i-1]*i%mod;
    while (~scanf("%d",&n)) 
        cout<<((a[n]*a[n]%mod)*qpow(a[2*n+1],mod-2))%mod<<endl;
    return 0;
}
View Code

 

 I   1 or 2

网络最大流题目,把题目所要求的规定连接路数看成是来源于此点的流量,如果最终能符合题目要求,那么来源于所有点的流量都可以分出去,最后通过超级汇点把所有点的流量收回来。

#include <bits/stdc++.h>
#define debug freopen("r.txt","r",stdin)
#define mp make_pair
#define ri register int
using namespace std;
typedef long long ll;
typedef pair<int, int> pii;
const int maxn = 1e6+10;
const int N = 5e4+10;
const int INF = 0x3f3f3f3f; 
const int mod = 998244353;
inline ll read(){ll s=0,w=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')w=-1;ch=getchar();}
while(ch>='0'&&ch<='9') s=s*10+ch-'0',ch=getchar();
return s*w;}
ll qpow(ll p,ll q){return (q&1?p:1)*(q?qpow(p*p%mod,q/2):1)%mod;}
struct FLOW{ //ISAP最大流
    struct edge{int to,w,nxt;}; //指向,限流,下一条边
    vector<edge> a; int head[N]; //前向星 
    int cur[N]; //当前弧 
    int n,s,t; //点数,源点,汇点
    queue<int> q;
    int dep[N],gap[N]; //gap[x]为等于x的dep[i]的个数
    void ae(int x,int y,int w){
        a.push_back((edge){y,w,head[x]});
        head[x]=a.size()-1;
    }
    bool bfs(){ //记录dep和gap
        fill(dep,dep+n,-1); dep[t]=0;
        fill(gap,gap+n,0); gap[0]=1;
        q.push(t);
        while(!q.empty()){
            int x=q.front(); q.pop();
            for(int i=head[x];i!=-1;i=a[i].nxt){
                int p=a[i].to;
                if(dep[p]!=-1)continue;
                dep[p]=dep[x]+1;
                q.push(p);
                gap[dep[p]]++;
            }
        }
        return dep[s]!=-1;
    }
    int dfs(int x,int fl){ //多路增广
        int now,ans=0;
        if(x==t)return fl;
        for(int i=cur[x];i!=-1;i=a[i].nxt){ //当前弧开始(可以不重复访问废边)
            cur[x]=i; //记录当前弧
            int p=a[i].to;
            if(a[i].w && dep[p]+1==dep[x])
            if((now=dfs(p,min(fl,a[i].w)))){
                a[i].w-=now;
                a[i^1].w+=now;
                ans+=now,fl-=now; //流量更新
                if(fl==0)return ans;
            }
        }
        gap[dep[x]]--;
        if(gap[dep[x]]==0)dep[s]=n;
        dep[x]++;
        gap[dep[x]]++;
        return ans;
    }
    void init(int _n){ //初始化
        n=_n+1;
        a.clear();
        fill(head,head+n,-1);
    }
    int solve(int _s,int _t){ //返回最大流
        s=_s,t=_t;
        int ans=0;
        if(bfs())
        while(dep[s]<n){
            copy(head,head+n,cur); //当前弧初始化
            ans+=dfs(s,INF);
        }
        return ans;
    }
}flow;
#define add(x,y,w) flow.ae(x,y,w),flow.ae(y,x,0)
//先flow.init(n),再add添边,最后flow.solve(s,t)
int a[maxn],m,n,i,x,y;
int main()
{
    while (~scanf("%d%d",&n,&m))
    {
        int sum=0;
        for (i=1;i<=n;i++) 
        {
            a[i]=read();
            sum+=a[i];
        }
        flow.init(n*2+1);
        int s,t;
        s=0,t=2*n+1;
        for (i=1;i<=m;i++)
        {
            x=read(),y=read();
            add(x,y+n,1);
            add(y,x+n,1);
        }
        for (i=1;i<=n;i++) 
        {
            add(s,i,a[i]);
            add(i+n,t,a[i]);
        }
        if (flow.solve(s,t)==sum) cout<<"Yes"<<endl;
            else cout<<"No"<<endl;
    }
    return 0;
}
View Code

 

posted @ 2020-07-15 23:14  Y-KnightQin  阅读(94)  评论(0编辑  收藏  举报