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 ivorysi
freopen("f1.in","r",stdin);
#endif
Solve();
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 ivorysi
freopen("f1.in","r",stdin);
#endif
Solve();
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 ivorysi
freopen("f1.in","r",stdin);
#endif
Solve();
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 ivorysi
freopen("f1.in","r",stdin);
#endif
Solve();
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 ivorysi
freopen("f1.in","r",stdin);
#endif
Solve();
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 ivorysi
freopen("f1.in","r",stdin);
#endif
Solve();
return 0;
}

【AtCoder】AGC005的更多相关文章

  1. 【AtCoder】AGC005 F - Many Easy Problems 排列组合+NTT

    [题目]F - Many Easy Problems [题意]给定n个点的树,定义S为大小为k的点集,则f(S)为最小的包含点集S的连通块大小,求k=1~n时的所有点集f(S)的和取模92484403 ...

  2. 【AtCoder】ARC092 D - Two Sequences

    [题目]AtCoder Regular Contest 092 D - Two Sequences [题意]给定n个数的数组A和数组B,求所有A[i]+B[j]的异或和(1<=i,j<=n ...

  3. 【Atcoder】CODE FESTIVAL 2017 qual A D - Four Coloring

    [题意]给定h,w,d,要求构造矩阵h*w满足任意两个曼哈顿距离为d的点都不同色,染四色. [算法]结论+矩阵变换 [题解] 曼哈顿距离是一个立着的正方形,不方便处理.d=|xi-xj|+|yi-yj ...

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

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

  5. 【AtCoder】AGC022 F - Leftmost Ball 计数DP

    [题目]F - Leftmost Ball [题意]给定n种颜色的球各k个,每次以任意顺序排列所有球并将每种颜色最左端的球染成颜色0,求有多少种不同的颜色排列.n,k<=2000. [算法]计数 ...

  6. 【AtCoder】ARC067 F - Yakiniku Restaurants 单调栈+矩阵差分

    [题目]F - Yakiniku Restaurants [题意]给定n和m,有n个饭店和m张票,给出Ai表示从饭店i到i+1的距离,给出矩阵B(i,j)表示在第i家饭店使用票j的收益,求任选起点和终 ...

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

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

  8. 【Atcoder】AGC022 C - Remainder Game 搜索

    [题目]C - Remainder Game [题意]给定n个数字的序列A,每次可以选择一个数字k并选择一些数字对k取模,花费2^k的代价.要求最终变成序列B,求最小代价或无解.n<=50,0& ...

  9. 【Atcoder】AGC 020 B - Ice Rink Game 递推

    [题意]n个人进行游戏,每轮只保留最大的a[i]倍数的人,最后一轮过后剩余2人,求最小和最大的n,或-1.n<=10^5. [算法]递推||二分 [题解]令L(i),R(i)表示第i轮过后的最小 ...

随机推荐

  1. php使用ZipArchive提示Fatal error: Class ZipArchive not found in的解决方法

    使用压缩包函数必须要安装zip扩展,否则会报错 $ apt install php-zip

  2. windows游戏编程X86 32位保护模式下的内存管理概述(一)

    本系列文章由jadeshu编写,转载请注明出处.http://blog.csdn.net/jadeshu/article/details/22445945 作者:jadeshu   邮箱: jades ...

  3. maven+SSM+junit+jetty+log4j2环境配置的最佳实践

    思路大致是 jetty插件 -> junit -> SpringMVC -> Spring -> log4j2 -> Mybatis整合 pom中的依赖跟着思路一批一批的 ...

  4. table表格整体居中

    代码: <div style="text-align:center"> <table border="1" cellpadding=" ...

  5. PHP 之验证码类封装

    一.效果图 二.类代码 <?php /** * Created by PhpStorm. * User: Yang * Date: 2019/8/13 * Time: 10:51 */ clas ...

  6. 表单事件集锦-input

    最近在写一个手机端提交表单的项目,里面用了不少input标签,因为项目不太忙,所以,想做的完美点,但是遇到了一些问题,比如:页面中的必填项如果有至少一项为空,提交按钮就是不能提交的状态,所以需要对所有 ...

  7. exposed beyond app through ClipData.Item.getUri()

    Android7.0调用相机时出现新的错误: android.os.FileUriExposedException: file:///storage/emulated/0/photo.jpeg exp ...

  8. C# DumpBin使用 查看反射C++ dll 动态链接库中的函数

    DumpBin是Microsoft提供的一个用于查看.exe..dll文件信息的工具,其位于: C:\Program Files (x86)\Microsoft Visual Studio 10.0\ ...

  9. Java HttpClient Post请求参数格式为XML

    1.最近忙着做一个接口,拿到文档的时候,what?我当时就震惊了,全都是XML数据传输. 我当时就懵了,哎没得办法,在暑假传输这方面笔者比较熟练json格式数据,简单易懂啊 那就学呗. 2.我在使用的 ...

  10. webpack 用 webpack-parallel-uglify-plugin 加速打包报错

    从新拉了份代码.npm install .npm run dev 都没有问题,但是npm run build 就报上面的错误了 查了好多资料,都没有解决上面的问题,也不知道是哪里出了问题,但是可以肯定 ...