AGC005

A - STring

用一个栈,如果遇到S就弹入,如果遇到T栈里有S就弹出栈顶,否则T在最后的串里,最后计算出的T和栈里剩的S就是答案

#include <bits/stdc++.h>
#define fi first
#define se second
#define pii pair<int,int>
#define mp make_pair
#define pb push_back
#define space putchar(' ')
#define enter putchar('\n')
#define eps 1e-10
#define MAXN 200005
//#define ivorysi
using namespace std;
typedef long long int64;
typedef unsigned int u32;
typedef double db;
template<class T>
void read(T &res) {res = 0;T f = 1;char c = getchar();while(c < '0' || c > '9') {if(c == '-') f = -1;c = getchar();}while(c >= '0' && c <= '9') {res = res * 10 +c - '0';c = getchar();}res *= f;
}
template<class T>
void out(T x) {if(x < 0) {x = -x;putchar('-');}if(x >= 10) {out(x / 10);}putchar('0' + x % 10);
}
char s[MAXN];
int top,N;
void Solve() {scanf("%s",s + 1);N = strlen(s + 1);int ans = 0;for(int i = 1 ; i <= N ; ++i) {if(s[i] == 'T') {if(top) --top;else ++ans;}else {++top;}}ans += top;out(ans);enter;
}
int main() {
#ifdef ivorysifreopen("f1.in","r",stdin);
#endifSolve();return 0;
}

B - Minimum Sum

就是单调栈求出左边最靠近它且比它小的数,右边最靠近且比它小的数,就可以计算出以这个点为最小值的区间有多少了

#include <bits/stdc++.h>
#define fi first
#define se second
#define pii pair<int,int>
#define mp make_pair
#define pb push_back
#define space putchar(' ')
#define enter putchar('\n')
#define eps 1e-10
#define MAXN 200005
//#define ivorysi
using namespace std;
typedef long long int64;
typedef unsigned int u32;
typedef double db;
template<class T>
void read(T &res) {res = 0;T f = 1;char c = getchar();while(c < '0' || c > '9') {if(c == '-') f = -1;c = getchar();}while(c >= '0' && c <= '9') {res = res * 10 +c - '0';c = getchar();}res *= f;
}
template<class T>
void out(T x) {if(x < 0) {x = -x;putchar('-');}if(x >= 10) {out(x / 10);}putchar('0' + x % 10);
}
int N,a[MAXN],l[MAXN],r[MAXN];
int sta[MAXN],top;
int64 ans = 0;
void Solve() {read(N);for(int i = 1 ; i <= N ; ++i) read(a[i]);for(int i = 1 ; i <= N ; ++i) {while(top && a[sta[top]] > a[i]) --top;l[i] = sta[top] + 1;sta[++top] = i;}top = 0;sta[0] = N + 1;for(int i = N ; i >= 1 ; --i) {while(top && a[sta[top]] > a[i]) --top;r[i] = sta[top] - 1;sta[++top] = i;}for(int i = 1 ; i <= N ; ++i) {ans += 1LL * (i - l[i] + 1) * (r[i] - i + 1) * a[i];}out(ans);enter;
}
int main() {
#ifdef ivorysifreopen("f1.in","r",stdin);
#endifSolve();return 0;
}

C - Tree Restoring

最大的A肯定是直径,如果直径是奇数,看看最小值是不是两个,其余的长度必须都大于等于2个

如果直径是偶数,看看最小值是不是1个,其余的长度必须大于等于两个

#include <bits/stdc++.h>
#define fi first
#define se second
#define pii pair<int,int>
#define mp make_pair
#define pb push_back
#define space putchar(' ')
#define enter putchar('\n')
#define eps 1e-10
#define MAXN 200005
//#define ivorysi
using namespace std;
typedef long long int64;
typedef unsigned int u32;
typedef double db;
template<class T>
void read(T &res) {res = 0;T f = 1;char c = getchar();while(c < '0' || c > '9') {if(c == '-') f = -1;c = getchar();}while(c >= '0' && c <= '9') {res = res * 10 +c - '0';c = getchar();}res *= f;
}
template<class T>
void out(T x) {if(x < 0) {x = -x;putchar('-');}if(x >= 10) {out(x / 10);}putchar('0' + x % 10);
}
int D,N,a[MAXN],cnt[MAXN];
void Solve() {read(N);for(int i = 1 ; i <= N ; ++i) {read(a[i]);cnt[a[i]]++;}for(int i = 1 ; i <= N ; ++i) D = max(D,a[i]);if(D & 1) {if(cnt[D / 2 + 1] != 2) {puts("Impossible");return;}int res = 0;for(int i = D / 2 + 1 ; i <= D ; ++i) {res += cnt[i];if(cnt[i] < 2) {puts("Impossible");return;}}if(res != N) {puts("Impossible");return;}}else {if(cnt[D / 2] != 1) {puts("Impossible");return;}int res = 1;for(int i = D / 2 + 1 ; i <= D ; ++i) {res += cnt[i];if(cnt[i] < 2) {puts("Impossible");return;}}if(res != N) {puts("Impossible");return;}}puts("Possible");return;
}
int main() {
#ifdef ivorysifreopen("f1.in","r",stdin);
#endifSolve();return 0;
}

D - ~K Perm Counting

用经典容斥,设\(g(i)\)为至少i个位置不合法的情况

答案就是\(\sum_{i = 0}^{n}(-1)^{i}g(i)\)

以\([1,2K - 1]\)开头,每\(2K\)个选择一个构成的这样的序列,这个序列当前的数每个能填什么,之和上一个数选择什么有关,这个可以用一个dp完成,然后可以得到每个序列里至少选了\(i\)个方案数

组合起来可以用NTT优化

#include <bits/stdc++.h>
#define fi first
#define se second
#define pii pair<int,int>
#define mp make_pair
#define pb push_back
#define space putchar(' ')
#define enter putchar('\n')
#define eps 1e-10
#define MAXN 2005
//#define ivorysi
using namespace std;
typedef long long int64;
typedef unsigned int u32;
typedef double db;
template<class T>
void read(T &res) {res = 0;T f = 1;char c = getchar();while(c < '0' || c > '9') {if(c == '-') f = -1;c = getchar();}while(c >= '0' && c <= '9') {res = res * 10 +c - '0';c = getchar();}res *= f;
}
template<class T>
void out(T x) {if(x < 0) {x = -x;putchar('-');}if(x >= 10) {out(x / 10);}putchar('0' + x % 10);
}
const int MOD = 924844033,g = 5,MAXL = (1 << 15);int N,K;
int a[MAXN],W[MAXL + 5],f[2][MAXN][2],p[MAXL + 5];
int ans[MAXL + 5],fac[MAXN];
int inc(int a,int b) {return a + b >= MOD ? a + b - MOD : a + b;
}
int mul(int a,int b) {return 1LL * a * b % MOD;
}
void update(int &x,int y) {x = inc(x,y);
}
int fpow(int x,int c) {int res = 1,t = x;while(c) {if(c & 1) res = mul(res,t);t = mul(t,t);c >>= 1;}return res;
}
void NTT(int *p,int L,int on) {for(int i = 1 , j = L >> 1 ; i < L - 1 ; ++i) {if(i < j) swap(p[i],p[j]);int k = L >> 1;while(j >= k) {j -= k;k >>= 1;}j += k;}for(int h = 2 ; h <= L ; h <<= 1) {int wn = W[(MAXL + on * MAXL / h) % MAXL];for(int k = 0 ; k < L ; k += h) {int w = 1;for(int j = k ; j < k + h / 2 ; ++j) {int u = p[j],t = mul(p[j + h / 2],w);p[j] = inc(u,t);p[j + h / 2] = inc(u,MOD - t);w = mul(w,wn);}}}if(on == -1) {int invL = fpow(L,MOD - 2);for(int i = 0 ; i < L ; ++i) p[i] = mul(p[i],invL);}
}
void Solve() {read(N);read(K);W[0] = 1;W[1] = fpow(g,(MOD - 1) / MAXL);for(int i = 2 ; i < MAXL ; ++i) W[i] = mul(W[i - 1],W[1]);int len = 1;while(len <= N) len <<= 1;ans[0] = 1;NTT(ans,len,1);for(int i = 1 ; i <= 2 * K ; ++i) {memset(f,0,sizeof(f));int cur = 0;f[cur][0][0] = 1;int cnt = 0;for(int j = i ; j <= N ; j += 2 * K) {memset(f[cur ^ 1],0,sizeof(f[cur ^ 1]));for(int h = 0 ; h <= cnt ; ++h) {update(f[cur ^ 1][h][0],inc(f[cur][h][0],f[cur][h][1]));if(j - K >= 1) update(f[cur ^ 1][h + 1][0],f[cur][h][0]);if(j + K <= N) update(f[cur ^ 1][h + 1][1],inc(f[cur][h][0],f[cur][h][1]));}++cnt;cur ^= 1;}memset(p,0,sizeof(p));for(int j = 0 ; j <= N ; ++j) {p[j] = inc(f[cur][j][0],f[cur][j][1]);}NTT(p,len,1);for(int j = 0 ; j < len ; ++j) {ans[j] = mul(ans[j],p[j]);}}NTT(ans,len,-1);fac[0] = 1;for(int i = 1 ; i <= N ; ++i) fac[i] = mul(fac[i - 1],i);int res = 0;for(int i = 0 ; i <= N ; ++i) {if(i & 1) update(res,MOD - mul(fac[N - i],ans[i]));else update(res,mul(fac[N - i],ans[i]));}out(res);enter;
}
int main() {
#ifdef ivorysifreopen("f1.in","r",stdin);
#endifSolve();return 0;
}

E - Sugigma: The Showdown

观察出-1的条件是先手走到一条红边的某个端点,这个红边的两个端点在蓝边树上的距离大于等于3

之后我们可以进行深搜,如果可以到某个点,先手和这个点的距离小于后手到达这个的距离就可以走,否则不行

如果走到特殊点输出-1,否则就是能走到的距离后手最远的距离乘2

#include <bits/stdc++.h>
#define fi first
#define se second
#define pii pair<int,int>
#define mp make_pair
#define pb push_back
#define space putchar(' ')
#define enter putchar('\n')
#define eps 1e-10
#define MAXN 200005
//#define ivorysi
using namespace std;
typedef long long int64;
typedef unsigned int u32;
typedef double db;
template<class T>
void read(T &res) {res = 0;T f = 1;char c = getchar();while(c < '0' || c > '9') {if(c == '-') f = -1;c = getchar();}while(c >= '0' && c <= '9') {res = res * 10 +c - '0';c = getchar();}res *= f;
}
template<class T>
void out(T x) {if(x < 0) {x = -x;putchar('-');}if(x >= 10) {out(x / 10);}putchar('0' + x % 10);
}
vector<int> to[2][MAXN];
int fa[MAXN][20],dep[MAXN];
int N,X,Y,ans;
bool flag = 0;
int lca(int u,int v) {if(dep[u] < dep[v]) swap(u,v);int l = 18;while(dep[u] > dep[v]) {if(dep[fa[u][l]] >= dep[v]) {u = fa[u][l];}--l;}if(u == v) return u;l = 18;while(fa[u][0] != fa[v][0]) {if(fa[u][l] != fa[v][l]) {u = fa[u][l];v = fa[v][l];}--l;}return fa[u][0];
}
int dist(int u,int v) {return dep[u] + dep[v] - 2 * dep[lca(u,v)];
}
void dfs(int u) {for(auto t : to[1][u]) {if(t != fa[u][0]) {dep[t] = dep[u] + 1;fa[t][0] = u;dfs(t);}}
}
void dfs1(int u,int f,int d) {if(u == Y) return;ans = max(ans,dep[u] - 1);for(auto t : to[0][u]) {if(t == f) continue;if(dist(u,t) > 2) flag = 1;if(d + 1 < dep[t] - 1) dfs1(t,u,d + 1);}
}
void Solve() {read(N);read(X);read(Y);int a,b;for(int i = 1 ; i < N ; ++i) {read(a);read(b);to[0][a].pb(b);to[0][b].pb(a);}for(int i = 1 ; i < N ; ++i) {read(a);read(b);to[1][a].pb(b);to[1][b].pb(a);}dep[Y] = 1;dfs(Y);for(int j = 1 ; j <= 19 ; ++j) {for(int i = 1 ; i <= N ; ++i) {fa[i][j] = fa[fa[i][j - 1]][j - 1];}}dfs1(X,0,0);if(flag) {puts("-1");}else {out(2 * ans);enter;}
}
int main() {
#ifdef ivorysifreopen("f1.in","r",stdin);
#endifSolve();return 0;
}

F - Many Easy Problems

我们把一个点的贡献转化为一条边的贡献,因为边的数量是点的数量-1,最后再加上选点方案数\(\binom{n}{k}\)即可

一条边的贡献是\(\binom{n}{k} - \binom{a}{k} - \binom{n - a}{k}\)就是在n个点里选k个点,去掉不合法的情况也就是k个点都在去掉这条边的两个子树里

然后我们要统计的就是\(\binom{a}{k} + \binom{n - a}{k}\)

这个可以转化成\(ans_{k} = \sum_{i = 1}^{n} b_{i} \binom{i}{k}\)

\(ans_{k} = \frac{1}{k!} \sum_{i = 1}^{n} b_{i} i! \frac{1}{(i - k)!}\)
这个数组是可以卷积的,只要把一个倒过来就行
设\(f(i) = \frac{1}{(n - i)!}\)
\(g(i) = b_{i}i!\)
\(h = g * f\)
\(ans_{k} = h(N + k)\)

代码

#include <iostream>
#include <cstdio>
#include <vector>
#include <algorithm>
#include <cmath>
#include <cstring>
#include <map>
//#define ivorysi
#define pb push_back
#define space putchar(' ')
#define enter putchar('\n')
#define mp make_pair
#define pb push_back
#define fi first
#define se second
#define mo 974711
#define RG register
#define MAXN 200005
using namespace std;
typedef long long int64;
typedef double db;
template<class T>
void read(T &res) {res = 0;char c = getchar();T f = 1;while(c < '0' || c > '9') {if(c == '-') f = -1;c = getchar();}while(c >= '0' && c <= '9') {res = res * 10 + c - '0';c = getchar();}res *= f;
}
template<class T>
void out(T x) {if(x < 0) {putchar('-');x = -x;}if(x >= 10) {out(x / 10);}putchar('0' + x % 10);
}
struct node {int to,next;
}E[MAXN * 2];
int head[MAXN],sumE;
void add(int u,int v) {E[++sumE].to = v;E[sumE].next = head[u];head[u] = sumE;
}
const int MOD = 924844033,L = (1 << 19),G = 5;
int N,f[L + 5],fac[MAXN],invfac[MAXN],b[L + 5],W[L + 5];
int mul(int a,int b) {return 1LL * a * b % MOD;}
int inc(int a,int b) {a = a + b;if(a >= MOD) a -= MOD;return a;}
int fpow(int x,int c) {int t = x,res = 1;while(c) {if(c & 1) res = mul(res,t);t = mul(t,t);c >>= 1;}return res;
}
int C(int n,int m) {if(n < m) return 0;return mul(mul(fac[n],invfac[m]),invfac[n - m]);
}
int dfs(int u,int fa) {int siz = 1;for(int i = head[u] ; i ; i = E[i].next) {int v = E[i].to;if(v != fa) {siz += dfs(v,u);}}if(fa != 0) {b[siz]++;b[N - siz]++;}return siz;
}
void NTT(int *a,int LEN,int on) {for(int i = 1 , j = LEN / 2 ; i < LEN - 1 ; ++i) {if(i < j) swap(a[i],a[j]);int k = LEN / 2;while(j >= k) {j -= k;k >>= 1;}j += k;}for(int h = 2 ; h <= LEN ; h <<= 1) {int wn = W[(L + on * L / h) % L];for(int k = 0 ; k < LEN ; k += h) {int w = 1;for(int j = k ; j < k + h / 2 ; ++j) {int64 u = a[j],t = 1LL * a[j + h / 2] * w;a[j] = (u + t) % MOD;a[j + h / 2] = (u - t + 1LL * MOD * MOD) % MOD;w = mul(w,wn);}}}if(on == -1) {int invL = fpow(LEN,MOD - 2);for(int i = 0 ; i < LEN ; ++i) a[i] = mul(a[i],invL);}
}
void Solve() {read(N);int u,v;for(int i = 1 ; i < N ; ++i) {read(u);read(v);add(u,v);add(v,u);}dfs(1,0);fac[0] = 1;for(int i = 1 ; i <= N ; ++i) fac[i] = mul(fac[i - 1],i);invfac[N] = fpow(fac[N],MOD - 2);for(int i = N - 1 ; i >= 0 ; --i) invfac[i] = mul(invfac[i + 1],i + 1);for(int i = 0 ; i <= N ; ++i) f[N - i] = invfac[i];for(int i = 1 ; i <= N ; ++i) b[i] = mul(b[i],fac[i]);W[0] = 1;W[1] = fpow(G,(MOD - 1) / L);for(int i = 2 ; i < L ; ++i) W[i] = mul(W[i - 1],W[1]);int t = 1;while(t <= 2 * N) t <<= 1;NTT(b,t,1);NTT(f,t,1);for(int i = 0 ; i < t ; ++i) f[i] = mul(f[i],b[i]);NTT(f,t,-1);for(int i = 1 ; i <= N ; ++i) {int ans = mul(f[i + N],invfac[i]);ans = inc(mul(N,C(N,i)),MOD - ans);out(ans);enter;}
}
int main() {
#ifdef ivorysifreopen("f1.in","r",stdin);
#endifSolve();return 0;
}

转载于:https://www.cnblogs.com/ivorysi/p/10890366.html

【AtCoder】AGC005相关推荐

  1. 【AtCoder】ARC 081 E - Don't Be a Subsequence

    [题意]给定长度为n(<=2*10^5)的字符串,求最短的字典序最小的非子序列字符串. http://arc081.contest.atcoder.jp/tasks/arc081_c [算法]字 ...

  2. 【Atcoder】ARC083 D - Restoring Road Network

    [算法]图论,最短路? [题意]原图为无向连通图,现给定原图的最短路矩阵,求原图最小边权和,n<=300. [题解]要求最小边权和下,原图的所有边一定是所连两端点的最短路. 那么现在将所有最短路 ...

  3. 【AtCoder】ARC095 E - Symmetric Grid 模拟

    [题目]E - Symmetric Grid [题意]给定n*m的小写字母矩阵,求是否能通过若干行互换和列互换使得矩阵中心对称.n,m<=12. [算法]模拟 [题解]首先行列操作独立,如果已确 ...

  4. 【atcoder】Enclosed Points [abc136F]

    题目传送门:https://atcoder.jp/contests/abc136/tasks/abc136_f 题目大意:在平面上有$n$个点我们,定义一个点集的权值为平面上包含这个点集的最小矩形所包 ...

  5. 【atcoder】GP 2 [agc036C]

    题目传送门:https://atcoder.jp/contests/agc036/tasks/agc036_c 题目大意:给你一个长度为$N$初始全0的序列,每次操作你可以找两个不同的元素,一个自增1 ...

  6. 【AtCoder】AGC034

    AGC034 刷了那么久AtCoder我发现自己还是只会ABCE(手动再见 A - Kenken Race 大意是一个横列,每个点可以跳一步或者跳两步,每个格子是空地或者石头,要求每一步不能走到石头或 ...

  7. 【Atcoder】AtCoder Beginner Contest 174总结

    目录 A Air Conditioner B Distance C Repsept D Alter Altar E Logs F Range Set Query A B C D E F √ √ ● ○ ...

  8. 【AtCoder】ARC088

    C - Multiple Gift 题解 首项是X,每次乘个2,暴力统计 代码 #include <bits/stdc++.h> #define fi first #define se s ...

  9. 【AtCoder】diverta 2019 Programming Contest 2

    diverta 2019 Programming Contest 2 A - Ball Distribution 特判一下一个人的,否则是\(N - (K - 1) - 1\) #include &l ...

最新文章

  1. FPGA之道(23)VHDL的signal、variable与constant
  2. 分布式配置中心disconf第三部(基于xml配置的实现原理)
  3. Pyserial 实现串口 base on python3
  4. 机器学习实战-KNN算法-20
  5. Move_base理解
  6. 华为鸿蒙系统正式拜拜,从“哄蒙”到“鸿蒙”,现在,正式对华为鸿蒙OS说你好!...
  7. maven项目动态替换配置中的值
  8. 关于前端处理表情符号问题(解决方案)
  9. 中国计算机学会(CCF)推荐中文科技期刊目录
  10. 由西云数据运营的中国第二个AWS区域正式向客户提供服务
  11. 我所了解的GB2312、Unicode、GBK、UTF-8、BIG5等编码
  12. Windows系统批量创建文件夹的技巧
  13. 一.隐藏手机下面虚拟键盘(华为,魅族......)
  14. HTML 小练习(智联注册页)
  15. Android绘制跟随路径移动的圆圈
  16. 友盟多渠道打包 Android Apk
  17. 基于微信小程序的共享课本系统 毕业设计毕设参考
  18. 汇编语言中间接寻址(间接操作数)与变址寻址(变址操作数)的区别
  19. WildFly:如何从位于另一个应用程序中的 EJB 调用 EJB
  20. svn中commit如何全选文件

热门文章

  1. JSF标签详解(全)
  2. 任正非自罚100万:“不要脸”的人,有多可怕?
  3. linux查看pid的用户名,在Linux中用Pstree命令及显示PID和PGID,显示命令行参数及突出显示...
  4. 基于c语言的象棋游戏
  5. 漫步者和南卡蓝牙耳机哪个好?高性价比蓝牙耳机测评
  6. 【完整代码】用HTML/CSS制作一个美观的个人简介网页
  7. CentOS7系统安装
  8. 【记录】在win10系统上安装ubuntu(乌班图)双系统
  9. 笔记-Java基础语法-二进制
  10. Axure RP9 安装教程