A
最后一位判定
#include <cstdlib> #include <cstdio> #include <algorithm> #include <cmath> #include <cstring> #include <queue> #include <vector> #include <map> #define P(x,y) 1ll * (x) * inv(y) % P using namespace std; typedef long long ll; const int N = 65005; const ll P = 1e9 + 7; int n; ll ans; char str[N]; int main(){ scanf("%d%s",&n,str + 1); for(int i = 1; i <= n; ++i){ if(!((str[i] - '0') & 1)) ans += i; } printf("%lld",ans); return 0; }
B
倒叙维护最大值
#include <cstdlib> #include <cstdio> #include <algorithm> #include <cmath> #include <cstring> #include <queue> #include <vector> #include <map> #define P(x,y) 1ll * (x) * inv(y) % P using namespace std; typedef long long ll; const int N = 2e5 + 5; const ll P = 1e9 + 7; int n,a[N],lim; ll ans; int main(){ scanf("%d",&n); for(int i = 1,x; i <= n; ++i){ scanf("%d",&a[i]); } lim = a[n]; ans += a[n]; for(int i = n - 1; i >= 1; --i){ lim = max(0,min(lim - 1,a[i])); ans += lim; } printf("%lld\n",ans); return 0; }
C
所有方案 - 全是红边的方案
并查集维护
#include <cstdlib> #include <cstdio> #include <algorithm> #include <cmath> #include <cstring> #include <queue> #include <vector> #include <map> #include <set> using namespace std; typedef long long ll; typedef pair<int,int> PII; const int N = 1e5 + 5; const ll P = 1e9 + 7; int n,m; ll ans; int size[N],fa[N]; inline ll qpow(ll x,ll y){ ll res = 1; while(y){ if(y & 1) res = res * x % P; x = x * x % P; y >>= 1; } return res; } int find(int x){return x == fa[x] ? x : fa[x] = find(fa[x]);} inline void merge(int x,int y){x = find(x),y = find(y),fa[x] = y,size[y] += size[x];} int main(){ scanf("%d%d",&m); ans = qpow(n,m); for(int i = 1; i <= n; ++i) fa[i] = i,size[i] = 1; for(int i = 1,x,y,z; i < n; ++i){ scanf("%d%d%d",&x,&y,&z); if(!z) merge(x,y); } for(int i = 1; i <= n; ++i){ if(fa[i] == i){ ans = (ans + P - qpow(size[i],m)) % P; } } printf("%lld\n",ans); return 0; }
然后我就自闭了?
D
给定数m \(m \leq 1e5\)
进行如下流程:
1.rand一个[1,m]的数
2.把它接在序列a后面
3.如果a的gcd等于1 退出 否则进行第一步
求进行流程次数的期望
前面那个\(\frac{(m-m/x)}{m}\)是抽到的数不是自己的倍数的概率
\(\frac{(m-m/x)}{m}*dp[x] = 1 + \sum_{d|x}^{m} \frac{dp[d]*c[d]}{m}\)
当然容斥那里用莫比乌斯函数也ok啦【因为懒所以这么写了
#include <cstdlib> #include <cstdio> #include <algorithm> #include <cmath> #include <cstring> #include <queue> #include <vector> #include <map> #include <set> using namespace std; typedef long long ll; typedef pair<int,int> PII; const int N = 1e5 + 5; const ll P = 1e9 + 7; inline ll qpow(ll x,ll y){ ll res = 1; while(y){ if(y & 1) res = res * x % P; x = x * x % P; y >>= 1; } return res; } int cnt[N],m,invm; vector<int> d[N]; ll f[N]; inline void init(){ for(int i = (m >> 1); i > 1; --i) for(int j = (i << 1); j <= m; j += i) d[j].push_back(i); invm = qpow(m,P - 2); } inline void cut(int x){ for(int i : d[x]) cnt[i] -= cnt[x]; } int main(){ scanf("%d",&m),init(); for(int i = 2; i <= m; ++i){ for(int j : d[i]) cnt[j] = m / j; cnt[i] = m / i,cut(i); for(int j : d[i]){ f[i] = (f[i] + f[j] * cnt[j] % P) % P; cut(j); } f[i] = ((f[i] + 1ll * m) % P * qpow(m - m / i,P - 2) % P) % P; } ll ans = 0; for(int i = 2; i <= m; ++i) ans = (ans + f[i]) % P; ans = (ans * invm % P + 1) % P; printf("%lld",ans); return 0; }
E
有n个点 m个集合
每个点有一个权值pi 有一个集合编号ci
每次删掉一个点之后查询每个集合选一个权值的最大mex
所有数据小于等于5000
倒着加边 边加边匹配
#include <cstdlib> #include <cstdio> #include <algorithm> #include <cmath> #include <cstring> #include <queue> #include <vector> #include <map> #include <set> #define mp(x,y) make_pair(x,y) using namespace std; typedef long long ll; typedef pair<int,int> PII; const int N = 5005; int n,m; struct Edge{int v,next;}edge[N]; int head[N],esize; inline void addedge(int x,int y){ edge[++esize] = (Edge){y,head[x]},head[x] = esize; } int p[N],c[N],day[N],ans; int d,bk[N],match[N]; bool vis[N],del[N]; bool dfs(int x){ for(int i = head[x],vv; ~i; i = edge[i].next){ vv = edge[i].v; if(!vis[vv]){ vis[vv] = 1; if(!match[vv] || dfs(match[vv])){ match[vv] = x; return 1; } } } return 0; } int main(){ memset(head,-1,sizeof(head)); scanf("%d%d",&m); for(int i = 1; i <= n; ++i) scanf("%d",&p[i]),++p[i]; for(int i = 1; i <= n; ++i) scanf("%d",&c[i]); scanf("%d",&d); for(int i = 1; i <= d; ++i) scanf("%d",&bk[i]),del[bk[i]] = 1; ans = 1; for(int i = 1; i <= n; ++i) if(!del[i]) addedge(p[i],c[i]); for(int i = d; i >= 1; --i){ memset(vis,sizeof(vis)); while(dfs(ans)){++ans; memset(vis,sizeof(vis));} day[i] = ans - 1; addedge(p[bk[i]],c[bk[i]]); } for(int i = 1; i <= d; ++i) printf("%d\n",day[i]); return 0; }
F
太神仙了慢慢搞 一眼扫描线?
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。