传送门

\(A\)

咕咕

const int N=5e5+5;
char s[N];int res,n,sum;
int main(){
scanf("%s",s+1),res=n=strlen(s+1);
fp(i,1,n)if(s[i]=='S')++sum;
else if(sum)--sum,res-=2;
printf("%d\n",res);
return 0;
}

\(B\)

咕咕

//quming
#include<bits/stdc++.h>
#define R register
#define fp(i,a,b) for(R int i=(a),I=(b)+1;i<I;++i)
#define fd(i,a,b) for(R int i=(a),I=(b)-1;i>I;--i)
#define go(u) for(int i=head[u],v=e[i].v;i;i=e[i].nx,v=e[i].v)
template<class T>inline bool cmin(T&a,const T&b){return a>b?a=b,1:0;}
template<class T>inline bool cmax(T&a,const T&b){return a<b?a=b,1:0;}
using namespace std;
typedef long long ll;
const int N=2e5+5,inf=0x3f3f3f3f;
int a[N],l[N],r[N],st[N],n,top;ll res;
int main(){
scanf("%d",&n);
fp(i,1,n)scanf("%d",&a[i]);
a[0]=a[n+1]=0,st[++top]=0;
fp(i,1,n){
while(top&&a[i]<a[st[top]])--top;
l[i]=st[top],st[++top]=i;
}
st[top=1]=n+1;
fd(i,n,1){
while(top&&a[i]<a[st[top]])--top;
r[i]=st[top],st[++top]=i;
}
fp(i,1,n)res+=1ll*a[i]*(i-l[i])*(r[i]-i);
printf("%lld\n",res);
return 0;
}

\(C\)

因为树上所有直径有同一个中点或同一条中边,那么\(dis\)最小的点只能有\(1\)个或者两个

然后我们从中点开始构造一条直径,如果无法构造出无解,否则剩下的点都可以挂在直径上而满足条件

最后判一下构造出的直径是否满足它给出的\(dis\)即可

const int N=105;
int c[N],n,mn=233,mx;
int main(){
scanf("%d",&n);
for(R int i=1,x;i<=n;++i)scanf("%d",&x),++c[x],cmin(mn,x),cmax(mx,x);
if(c[mn]>2)return puts("Impossible"),0;
fp(i,mn+1,mx)if(c[i]<2)return puts("Impossible"),0;
if(c[mn]==2&&mn!=mx-mn+1)return puts("Impossible"),0;
if(c[mn]==1&&mn!=mx-mn)return puts("Impossible"),0;
return puts("Possible"),0;
}

\(D\)

这种题目显然是容斥了

然而如果直接枚举有几个点选了不该选的数会有问题,因为有的点选不该选的数有两种方案,有的点选了别的点就不能选

发现选了之后\(i\)只会影响\(...,i-4k,i-2k,i+2k,i+4k,...\)的数的选法,那么我们把所有模\(2k\)意义下相等的位置一起考虑,记\(f_{i,j,0/1/2}\)表示考虑到这一类中的第\(i\)个数,选了其中\(j\)个,第\(i\)个数不选\(/\)选择在这个位置放\(i-k/\)选择在这个位置放\(i+k\)的方案数,转移即可,最后暴力加到全局的背包里,即可计算出\(s[i]\)表示至少有这\(i\)个位置选择不合法的方案数,就可以直接套容斥了

//quming
#include<bits/stdc++.h>
#define R register
#define fp(i,a,b) for(R int i=(a),I=(b)+1;i<I;++i)
#define fd(i,a,b) for(R int i=(a),I=(b)-1;i>I;--i)
#define go(u) for(int i=head[u],v=e[i].v;i;i=e[i].nx,v=e[i].v)
template<class T>inline bool cmin(T&a,const T&b){return a>b?a=b,1:0;}
template<class T>inline bool cmax(T&a,const T&b){return a<b?a=b,1:0;}
using namespace std;
const int P=924844033;
inline void upd(R int &x,R int y){(x+=y)>=P?x-=P:0;}
inline int add(R int x,R int y){return x+y>=P?x+y-P:x+y;}
inline int dec(R int x,R int y){return x-y<0?x-y+P:x-y;}
inline int mul(R int x,R int y){return 1ll*x*y-1ll*x*y/P*P;}
int ksm(R int x,R int y){
R int res=1;
for(;y;y>>=1,x=mul(x,x))(y&1)?res=mul(res,x):0;
return res;
}
const int N=2005;
int n,k,res,len,f[N][3],g[N][3],s[N],t[N],fac[N];
void calc(R int x){
memset(f,0,sizeof(f));
f[0][0]=1;
R int p=0;
for(;x<=n;x+=(k<<1)){
fp(i,0,p){
g[i][0]=f[i][0],g[i][1]=f[i][1],g[i][2]=f[i][2];
f[i][0]=f[i][1]=f[i][2]=0;
}
fp(i,0,p){
R int s=add(g[i][0],add(g[i][1],g[i][2]));
upd(f[i][0],s);
if(x>k)upd(f[i+1][1],dec(s,g[i][2]));
if(x+k<=n)upd(f[i+1][2],s);
}
++p;
}
memset(t,0,sizeof(t));
fp(i,0,len)fp(j,0,p)upd(t[i+j],mul(s[i],add(f[j][0],add(f[j][1],f[j][2]))));
len+=p;
fp(i,0,len)s[i]=t[i];
}
int main(){
// freopen("testdata.in","r",stdin);
scanf("%d%d",&n,&k);
fac[0]=1;fp(i,1,n)fac[i]=mul(fac[i-1],i);
s[0]=1;
fp(i,1,min(k<<1,n))calc(i);
fp(i,0,len)upd(res,i&1?dec(0,mul(fac[n-i],s[i])):mul(fac[n-i],s[i]));
printf("%d\n",res);
return 0;
}

\(E\)

博弈论菜鸡在此

首先如果存在一个情况,\(A\)在\(u\),\(B\)在\(v\),如果\(u\)能走到的任何一条边在蓝树上到\(v\)的距离都小于等于\(1\),\(A\)只能等死了,否则如果存在一条边\((u,v)\)满足蓝树上的距离大于\(2\),那么\(A\)就可以一直利用这条边绕\(B\)了,此时输出\(-1\)

如果会被追到,那么以蓝树上的\(Y\)为根,我们发现\(A\)根本走不出这棵子树,那么我们找到所有\(A\)能到达的点,然后到其中深度最大的点等死就行了

//quming
#include<bits/stdc++.h>
#define R register
#define fp(i,a,b) for(R int i=(a),I=(b)+1;i<I;++i)
#define fd(i,a,b) for(R int i=(a),I=(b)-1;i>I;--i)
#define go(head,u) for(int i=head[u],v=e[i].v;i;i=e[i].nx,v=e[i].v)
template<class T>inline bool cmin(T&a,const T&b){return a>b?a=b,1:0;}
template<class T>inline bool cmax(T&a,const T&b){return a<b?a=b,1:0;}
using namespace std;
const int N=1e6+5;
struct eg{int v,nx;}e[N<<1];int bl[N],rd[N],tot;
inline void add(R int *head,R int u,R int v){e[++tot]={v,head[u]},head[u]=tot;}
int fr[N],to[N],dep[N],fa[N],dfn[N],low[N],ok[N],vis[N],dis[N],tim,n,S,T;
void dfs(int *head,int u){
dfn[u]=++tim;
go(head,u)if(v!=fa[u])fa[v]=u,dep[v]=dep[u]+1,dfs(head,v);
low[u]=tim;
}
inline bool ck(R int u,R int v){
if(dfn[u]>dfn[v])swap(u,v);if(low[u]>=low[v])return dep[v]-dep[u]>2;
if(fa[u]==fa[v])return false;return true;
}
int q[N];
void bfs(){
int h=1,t=0,u;q[++t]=S,vis[S]=1;
while(h<=t){
u=q[h++];
go(rd,u)if(!vis[v]){
dis[v]=dis[u]+1;
if(dis[v]<dep[v])vis[v]=1,q[++t]=v;
}
}
}
int main(){
scanf("%d%d%d",&n,&S,&T);
for(R int i=1,u,v;i<n;++i)scanf("%d%d",&u,&v),fr[i]=u,to[i]=v;
for(R int i=1,u,v;i<n;++i)scanf("%d%d",&u,&v),add(bl,u,v),add(bl,v,u);
dfs(bl,T);
for(R int i=1,u,v;i<n;++i){
u=fr[i],v=to[i];
if(ck(u,v))ok[u]=ok[v]=1;
else add(rd,u,v),add(rd,v,u);
}
bfs();
fp(i,1,n)if(vis[i]&&ok[i])return puts("-1"),0;
R int res=0;
fp(i,1,n)if(vis[i])cmax(res,dep[i]<<1);
printf("%d\n",res);
return 0;
}

\(F\)

先考虑如何计算单个\(k\),那么对于每个点分别计算贡献,一个点会被计入贡献的次数是\({n\choose k}-\sum_{v\in son_u}{sz_v\choose k}\),其中\(sz_v\)表示以\(u\)为根时\(v\)子树的大小

那么\(n\)个点加起来就是\(n\times {n\choose k}-\sum_{i=1}^n cnt[i]\times {i\choose k}\),把组合数拆成阶乘的形式就可以把后面看成一个卷积了,\(NTT\)即可

//quming
#include<bits/stdc++.h>
#define R register
#define fp(i,a,b) for(R int i=(a),I=(b)+1;i<I;++i)
#define fd(i,a,b) for(R int i=(a),I=(b)-1;i>I;--i)
#define go(u) for(int i=head[u],v=e[i].v;i;i=e[i].nx,v=e[i].v)
template<class T>inline bool cmax(T&a,const T&b){return a<b?a=b,1:0;}
template<class T>inline bool cmin(T&a,const T&b){return a>b?a=b,1:0;}
using namespace std;
const int P=924844033,gi=554906420;
inline void upd(R int &x,R int y){(x+=y)>=P?x-=P:0;}
inline int add(R int x,R int y){return x+y>=P?x+y-P:x+y;}
inline int dec(R int x,R int y){return x-y<0?x-y+P:x-y;}
inline int mul(R int x,R int y){return 1ll*x*y-1ll*x*y/P*P;}
int ksm(R int x,R int y){
R int res=1;
for(;y;y>>=1,x=mul(x,x))(y&1)?res=mul(res,x):0;
return res;
}
const int N=(1<<19)+5;
struct eg{int v,nx;}e[N<<1];int head[N],tot;
inline void Add(R int u,R int v){e[++tot]={v,head[u]},head[u]=tot;}
int fac[N],ifac[N],r[25][N],rt[2][N],f[N],g[N],inv[25];
int n,lim,d;
inline void swap(R int &x,R int &y){R int t=x;x=y,y=t;}
inline int C(R int n,R int m){return m>n?0:1ll*fac[n]*ifac[m]%P*ifac[n-m]%P;}
void init(){
fac[0]=ifac[0]=1;fp(i,1,262144)fac[i]=mul(fac[i-1],i);
ifac[262144]=ksm(fac[262144],P-2);fd(i,262143,1)ifac[i]=mul(ifac[i+1],i+1);
fp(d,1,19){
fp(i,1,(1<<d)-1)r[d][i]=(r[d][i>>1]>>1)|((i&1)<<(d-1));
inv[d]=ksm(1<<d,P-2);
}
for(R int t=(P-1)>>1,i=1,x,y;i<=262144;i<<=1,t>>=1){
x=ksm(5,t),y=ksm(gi,t),rt[0][i]=rt[1][i]=1;
fp(k,1,i-1)
rt[1][i+k]=mul(rt[1][i+k-1],x),
rt[0][i+k]=mul(rt[0][i+k-1],y);
}
}
void NTT(int *A,int ty){
fp(i,0,lim-1)if(i<r[d][i])swap(A[i],A[r[d][i]]);
R int t;
for(R int mid=1;mid<lim;mid<<=1)
for(R int j=0;j<lim;j+=(mid<<1))
fp(k,0,mid-1)
A[j+k+mid]=dec(A[j+k],t=mul(rt[ty][mid+k],A[j+k+mid])),
A[j+k]=add(A[j+k],t);
if(!ty){
t=inv[d];
fp(i,0,lim-1)A[i]=mul(A[i],t);
}
}
int sz[N];
void dfs(int u,int fa){
sz[u]=1;
go(u)if(v!=fa){
dfs(v,u),sz[u]+=sz[v];
++f[n-sz[v]],++f[sz[v]];
}
}
int main(){
// freopen("testdata.in","r",stdin);
scanf("%d",&n);
for(R int i=1,u,v;i<n;++i)scanf("%d%d",&u,&v),Add(u,v),Add(v,u);
dfs(1,0);init();
lim=1,d=0;
while(lim<=(n<<1))lim<<=1,++d;
fp(i,0,n)f[i]=mul(f[i],fac[i]),g[i]=ifac[n-i];
NTT(f,1),NTT(g,1);
fp(i,0,lim-1)f[i]=mul(f[i],g[i]);
NTT(f,0);
fp(i,1,n)printf("%d\n",dec(mul(n,C(n,i)),mul(f[i+n],ifac[i])));
return 0;
}

AtCoder Grand Contest 005题解的更多相关文章

  1. AtCoder Grand Contest 005

    AtCoder Grand Contest 005 A - STring 翻译 给定一个只包含\(ST\)的字符串,如果出现了连续的\(ST\),就把他删去,然后所有位置前移.问最后剩下的串长. 题解 ...

  2. AtCoder Grand Contest 017 题解

    A - Biscuits 题目: 给出 \(n\) 个物品,每个物品有一个权值. 问有多少种选取方式使得物品权值之和 \(\bmod\space 2\) 为 \(p\). \(n \leq 50\) ...

  3. AtCoder Grand Contest 005 C - Tree Restoring

    题目传送门:https://agc005.contest.atcoder.jp/tasks/agc005_c 题目大意: 给定一个长度为\(N\)的整数序列\(A_i\),问能否构造一个\(N\)个节 ...

  4. Atcoder Grand Contest 005 E - Sugigma: The Showdown(思维题)

    洛谷题面传送门 & Atcoder 题面传送门 记先手移动棋子的树为红树,后手移动棋子的树为蓝树. 首先考虑一个性质,就是如果与当前红色棋子所在的点相连的边中存在一条边,满足这条边的两个端点在 ...

  5. Atcoder Grand Contest 054 题解

    那天晚上由于毕业晚会与同学吃饭喝酒没打 AGC,第二天稍微补了下题,目前补到了 E,显然 AGC 的 F 对于我来说都是不可做题就没补了(bushi A 简单题,不难发现如果我们通过三次及以上的操作将 ...

  6. AtCoder Grand Contest 030题解

    第一次套刷AtCoder 体验良好 传送门 Poisonous Cookies cout<<b+min(c,a+b+); Tree Burning 难度跨度有点大啊 可以证明当第一次转向之 ...

  7. AtCoder Grand Contest 031题解

    题面 传送门 题解 比赛的之后做完\(AB\)就开始发呆了--简直菜的一笔啊-- \(A - Colorful\ Subsequence\) 如果第\(i\)个字母选,那么它前面任意一个别的字母的选择 ...

  8. AtCoder Grand Contest 005【A栈模拟,B单调栈】

    挖草,AtCoder实在是太吊了~ %%%,目前只A了两题: A题: 就是利用栈模拟一下就好了:S进栈,T的话有S就出栈,然后len减一下就好了: #include <bits/stdc++.h ...

  9. AtCoder Grand Contest 039 题解

    传送门 \(A\) 首先只有一串的情况下,遇到相同的肯定是改后面那一个最优,然后两串的话可能要分奇偶讨论一下 //quming #include<bits/stdc++.h> #defin ...

随机推荐

  1. 玩转Spring全家桶笔记 04 Spring的事务抽象、事务传播特性、编程式事务、申明式事务

    1.Spring 的事务抽象 Spring提供了一致的事务模型 JDBC/Hibernate/Mybatis 操作数据 DataSource/JTA 事务 2.事务抽象的核心接口 PlatformTr ...

  2. session 在PC端正常设置读取,在移动端无法正常读取

    一.背景 最近在做一个面向三端[H5.IOS.安卓]的短信验证码登录接口.发送短信验证码时,服务端通过 session 保存验证码的值.登录时,从 session 获取验证码和用户输入的验证码 相比较 ...

  3. Oracle 用户模式

    在 Oracle 数据库中,为了便于管理用户所创建的数据库对象(数据表.索引.视图等),引入了模式的概念,这样某个用户所创建的数据库对象就都属于该用户模式. 一.模式与模式对象 模式是一个数据库对象的 ...

  4. self attention pytorch代码

    实现细节; 1.embedding 层 2.positional encoding层:添加位置信息 3,MultiHeadAttention层:encoder的self attention 4,sub ...

  5. Jmeter学习笔记(十)——元件的作用域和执行顺序

    jmeter是一个开源的性能测试工具,它可以通过鼠标拖拽来随意改变元件之间的顺序以及元件的父子关系,那么随着它们的顺序和所在的域不同,它们在执行的时候,也会有很多不同. jmeter的test pla ...

  6. Arm存储器

    Arm可以引出27根地址线,只能实现128MB的寻址,那么要如何实现1GB的寻址呢?答案就是使用nGCS片选线,nGCSx为低电平为选中相应的外接设备.一共八根片选线,也就是bank1,bank2-以 ...

  7. VsCode使用setting sync 同步自己的插件和设置等

    直接再 Vscode中安装就可以,然后: 1. 可以点看setting sync插件在vscode 这个时候可以按照提示进行设置(也可以参考下:https://www.cnblogs.com/kenz ...

  8. AutoMapper 初次使用心得

    本例以asp.net webform为例: 结构: 主要代码:AutoMapperConfig 类 public class AutoMapperConfig { public static void ...

  9. MySQL关闭缓慢

    Pre环境有个MySQL不能进行数据写入操作,关闭实例也非常慢,最后error报错. 最后发现是磁盘不能进行写操作. touch /data/testtouch: cannot touch ‘/dat ...

  10. Python——Int&Bool

    整数类型: int类型,多用于数字运算 print(666) print(6+1) 整数类型转换: v1 = 666 v2 = str(v1) #会得出字符串的666 v1 = True v2 = i ...