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; }
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; }