Codechef October Challenge 2019 Division 1
Preface
这次CC难度较上两场升高了许多,后面两题都只能借着曲明姐姐和jz姐姐的仙气来做
值得一提的是原来的F大概需要大力分类讨论,结果我写了一大半题目就因为原题被ban了233
最后勉强涨了近200分,下场如果不出意外地话应该可以打到六星。(ORZ七星julao LTL)
A Chef and Maximum Star Value
SB题,可以设一个阈值统计也可以直接根号大暴力,反正都能过
#include<cstdio>
#include<iostream>
#define RI register int
using namespace std;
const int N=100005;
int t,n,x,ct[N*10],ans,mx;
int main()
{
for (scanf("%d",&t);t;--t)
{
RI i,j; for (scanf("%d",&n),ans=mx=0,i=1;i<=n;++i)
{
scanf("%d",&x); ans=max(ans,ct[x]); mx=max(mx,x);
for (j=1;j*j<=x;++j) if (x%j==0)
{
++ct[j]; if (x!=j*j) ++ct[x/j];
}
}
for (printf("%d\n",ans),i=1;i<=mx;++i) ct[i]=0;
}
}
B Array Modification
考虑一个数\(x\),与它对应位置的数记为\(y\),则\((x,y)\to (x\operatorname{xor}y,x)\to(y,x\operatorname{xor} y)\to (x,y)\)
意味着做\(3\times k\)次就会循环出现,然后膜一下再暴力跑即可
WARNING:注意\(n\)为奇数是最中间一个数做一次就变成\(0\)了
#include<cstdio>
#define RI register int
using namespace std;
const int N=10005;
int t,n,a[N]; long long k;
int main()
{
for (scanf("%d",&t);t;--t)
{
RI i; scanf("%d%lld",&n,&k);
for (i=1;i<=n;++i) scanf("%d",&a[i]);
if ((n&1)&&k>=(n+1>>1)) a[n+1>>1]=0; k%=3*n;
for (i=1;k;--k,i=i!=n?i+1:1) a[i]^=a[n-i+1];
for (i=1;i<=n;++i) printf("%d%c",a[i]," \n"[i==n]);
}
return 0;
}
C Even Edges
分类讨论。首先\(m\)为偶数显然不需要分,直接输出\(1\)
如果\(m\)为奇数但是存在任意一个点度数为奇数那么直接把它单独拿出来即可,答案为\(2\)
如果没有奇数度数点怎么办,手动构造啊,先随便找一条边拿出其中的一个点,那么剩下的那个点的度数必然是奇数了,重复上面的方法因此答案为3
#include<cstdio>
#define RI register int
using namespace std;
const int N=100005;
int t,n,m,deg[N],x,y;
inline void clear(void)
{
for (RI i=1;i<=n;++i) deg[i]=0;
}
int main()
{
for (scanf("%d",&t);t;--t)
{
RI i; for (scanf("%d%d",&n,&m),i=1;i<=m;++i)
scanf("%d%d",&x,&y),++deg[x],++deg[y];
if (!(m&1))
{
for (puts("1"),i=1;i<=n;++i) printf("%d%c",1," \n"[i==n]);
clear(); continue;
}
bool flag=0; for (i=1;i<=n;++i)
if (deg[i]&1) { flag=1; x=i; break; }
if (flag)
{
for (puts("2"),i=1;i<=n;++i) printf("%d%c",i==x?1:2," \n"[i==n]);
clear(); continue;
}
for (puts("3"),i=1;i<=n;++i) printf("%d%c",i==x?1:(i==y?2:3)," \n"[i==n]); clear();
}
return 0;
}
D Bacterial Reproduction
稍微要动下脑子的一题。注意到我们只需要对于节点的性质进行讨论即可:
- 若该点为叶节点,那么从根到它的路径上所有能在规定时间之内到达它的(大于的区间)都可以对他都能造成贡献
- 若该点不是叶节点,那么从根到它的路径上所有能在规定时间之时(单点)到达它的(大于的区间)都可以对他都能造成贡献
那么我们离线处理问题,DFS处理修改,可以用时间减去深度维护下标,用树状数组维护即可
#include<cstdio>
#include<cctype>
#include<vector>
#define int long long
#define RI register int
#define CI const int&
#define pb push_back
#define mp make_pair
using namespace std;
typedef pair <int,int> pi;
const int N=500005;
struct edge
{
int to,nxt;
}e[N<<1]; int n,q,head[N],cnt,x,y,ans[N],deg[N];
vector <pi> ps[N]; vector <int> qs[N];
inline char get(void)
{
char ch; while (isspace(ch=getchar())); return ch;
}
inline void addedge(CI x,CI y)
{
e[++cnt]=(edge){y,head[x]}; head[x]=cnt; ++deg[x];
e[++cnt]=(edge){x,head[y]}; head[y]=cnt; ++deg[y];
}
class Tree_Array
{
private:
int bit[N<<1];
public:
#define lowbit(x) x&-x
inline void add(RI x,CI y)
{
for (x+=n+1;x<=n+q+1;x+=lowbit(x)) bit[x]+=y;
}
inline int get(RI x,int ret=0)
{
for (x+=n+1;x;x-=lowbit(x)) ret+=bit[x]; return ret;
}
#undef lowbit
}BIT;
#define to e[i].to
inline void DFS(CI now=1,CI fa=0,CI dep=0)
{
for (vector <pi>::iterator it=ps[now].begin();it!=ps[now].end();++it)
BIT.add(it->first-dep,it->second);
for (vector <int>::iterator it=qs[now].begin();it!=qs[now].end();++it)
if (deg[now]==1) ans[*it]=BIT.get(*it-dep);
else ans[*it]=BIT.get(*it-dep)-BIT.get(*it-dep-1);
for (RI i=head[now];i;i=e[i].nxt) if (to!=fa) DFS(to,now,dep+1);
for (vector <pi>::iterator it=ps[now].begin();it!=ps[now].end();++it)
BIT.add(it->first-dep,-it->second);
}
#undef to
signed main()
{
RI i; for (scanf("%lld%lld",&n,&q),i=1;i<n;++i)
scanf("%lld%lld",&x,&y),addedge(x,y);
if (n==1) deg[1]=1; else deg[1]=0;
for (i=1;i<=n;++i) scanf("%lld",&x),ps[i].pb(mp(0,x));
for (i=1;i<=q;++i) if (get()=='?') scanf("%lld",&x),qs[x].pb(i);
else scanf("%lld%lld",&x,&y),ps[x].pb(mp(i,y)),ans[i]=-1;
for (DFS(),i=1;i<=q;++i) if (~ans[i]) printf("%lld\n",ans[i]);
return 0;
}
F Queries on Matrix
本来只会一个\(O(n^3\log Q)\)的暴力方法,主要就是分别考虑行和列的贡献(有多少个是奇数)
然后DP设\(f_{i,j}\)表示做了\(i\)次,有\(j\)行奇数的方案数,显然有转移\(f_{i,j}=f_{i-1,j-1}\times (n-j+1)+f_{i-1,j+1}\times(j+1)\),结合矩阵快速幂转移即可
正解么,生成函数大法好!(让我们一起来膜拜jz姐姐吧)
由于做法比较大力因此可能需要卡常,这里的代码把多项式中的系数为\(0\)的项省略了
#include<cstdio>
#include<vector>
#include<iostream>
#define RI register int
#define CI const int&
#define pb push_back
using namespace std;
typedef vector <int> VI;
const int N=2005,mod=998244353,inv2=mod+1>>1;
VI A,B,PB[N]; int r[N],c[N];
// A: e^x-e^-x ; B: e^x+e^-x
// use half space and ignore 0
int t,n,m,z,pw[N],fact[N],inv[N],ipw2[N]; long long q;
inline int quick_pow(int x,int p=mod-2,int mul=1)
{
for (;p;p>>=1,x=1LL*x*x%mod) if (p&1) mul=1LL*mul*x%mod; return mul;
}
inline void inc(int& x,CI y)
{
if ((x+=y)>=mod) x-=mod;
}
inline void dec(int& x,CI y)
{
if ((x-=y)<0) x+=mod;
}
inline VI operator * (const VI& A,const VI& B)
{
CI na=A.size(),nb=B.size(); VI C(na+nb-1);
for (RI i=0;i<na;++i) for (RI j=0;j<nb;++j)
inc(C[i+j],1LL*A[i]*B[j]%mod); return C;
}
inline void Div(VI& A) // A/=(e^x+e^-x)
{
CI na=A.size(); VI C(na); RI i;
for (i=na-1;~i;--i) if (A[i])
{
C[i]=A[i]; if (i) dec(A[i-1],A[i]);
}
bool flag=0; for (A.clear(),i=0;i<na;++i)
{
if (C[i]) flag=1; if (flag) A.pb(C[i]);
}
}
inline void DEBUG(const VI& P)
{
int cp=P.size(); for (RI i=0;i<cp;++i) printf("%d ",P[i]); putchar('\n');
}
inline int init(CI n=2000)
{
RI i; for (fact[0]=i=1;i<=n;++i) fact[i]=1LL*fact[i-1]*i%mod;
for (inv[n]=quick_pow(fact[n]),i=n-1;~i;--i) inv[i]=1LL*inv[i+1]*(i+1)%mod;
for (ipw2[0]=i=1;i<=n;++i) ipw2[i]=1LL*ipw2[i-1]*inv2%mod;
for (A.pb(mod-1),A.pb(1),B.pb(1),B.pb(1),PB[0].pb(1),i=1;i<=n;++i) PB[i]=PB[i-1]*B;
}
inline int C(CI n,CI m)
{
return 1LL*fact[n]*inv[m]%mod*inv[n-m]%mod;
}
inline int calc(const VI& A,CI c,int ret=0)
{
RI i,j; for (i=j=c;j>0;--i,j-=2) inc(ret,1LL*A[i]*pw[j]%mod);
for (i=0,j=c;j>0;++i,j-=2) if (q&1) dec(ret,1LL*A[i]*pw[j]%mod);
else inc(ret,1LL*A[i]*pw[j]%mod); return ret;
}
inline void solve(int *a,CI n)
{
VI P=PB[n]; RI i; int cp=P.size(); for (i=0;i<cp;++i) P[i]=1LL*P[i]*ipw2[n]%mod;
for (a[0]=calc(P,n),i=1;i<=n;++i) P=P*A,Div(P),a[i]=1LL*calc(P,n)*C(n,i)%mod;
}
int main()
{
for (init(),scanf("%d",&t);t;--t)
{
RI i,j; int ans=0; scanf("%d%d%lld%d",&n,&m,&q,&z);
for (pw[0]=i=1;i<=max(n,m);++i)
pw[i]=quick_pow(i,q%(mod-1));
for (solve(r,n),solve(c,m),i=0;i<=n;++i) for (j=0;j<=m;++j)
if (i*(m-j)+j*(n-i)==z) inc(ans,1LL*r[i]*c[j]%mod);
printf("%d\n",ans);
}
return 0;
}
G Faulty System
论文题真有趣。直接看IOI2018中国国家候选队论文集里的拟阵部分即可
注意这里的拟阵定义就是里面的图拟阵,拟阵交的具体算法实现也都在里面了
#include<cstdio>
#include<cstring>
#define RI register int
#define CI const int&
using namespace std;
const int N=305;
struct edge
{
int to,nxt;
}e[N*N]; int t,n,m,head[N],cnt;
struct Graph_Matroid
{
int x[N],y[N],fa[N];
inline int getfa(CI x)
{
return x!=fa[x]?fa[x]=getfa(fa[x]):x;
}
inline void init(void)
{
for (RI i=1;i<=n;++i) fa[i]=i;
}
inline void Union(CI p)
{
fa[getfa(x[p])]=getfa(y[p]);
}
inline bool identify(CI p)
{
return getfa(x[p])==getfa(y[p]);
}
}A,B; int C[N],q[N],pre[N],tot; bool cs[N],st[N],tar[N],rch[N],vis[N];
inline void addedge(CI x,CI y)
{
e[++cnt]=(edge){y,head[x]}; head[x]=cnt;
}
inline void DEBUG(bool *a)
{
for (RI i=1;i<=m;++i) printf("%d%c",a[i]," \n"[i==m]);
}
#define to e[i].to
inline bool BFS(void)
{
RI H=0,T=0,i,now; memset(rch,0,m+1); memset(pre,0,m+1<<2);
for (i=1;i<=m;++i) if (st[i]) q[++T]=i,rch[i]=1;
while (H<T)
{
now=q[++H]; if (tar[now]) break;
for (i=head[now];i;i=e[i].nxt) if (!rch[to])
rch[to]=1,q[++T]=to,pre[to]=now;
}
if (!tar[now]) return 0; for (;now;now=pre[now]) vis[now]=1; return 1;
}
#undef to
inline int Cross(void)
{
for (tot=0,memset(cs,0,m+1);;)
{
RI i,j; for (memset(head,0,m+1<<2),cnt=0,i=1;i<=tot;++i)
{
for (A.init(),B.init(),j=1;j<=tot;++j)
if (i!=j) A.Union(C[j]),B.Union(C[j]);
for (j=1;j<=m;++j) if (!cs[j])
{
if (!A.identify(j)) addedge(C[i],j);
if (!B.identify(j)) addedge(j,C[i]);
}
}
memset(st,0,m+1); memset(tar,0,m+1); memset(vis,0,m+1);
for (A.init(),B.init(),i=1;i<=tot;++i) A.Union(C[i]),B.Union(C[i]);
for (i=1;i<=m;++i) if (!cs[i]) st[i]=!A.identify(i),tar[i]=!B.identify(i);
//DEBUG(st); DEBUG(tar); DEBUG(cs);
if (!BFS()) break; for (tot=0,i=1;i<=m;++i) if (cs[i]^vis[i]) C[++tot]=i;
for (memset(cs,0,m+1),i=1;i<=tot;++i) cs[C[i]]=1;
}
return tot;
}
int main()
{
//freopen("CODE.in","r",stdin); freopen("CODE.out","w",stdout);
for (scanf("%d",&t);t;--t)
{
RI i; for (scanf("%d%d",&n,&m),i=1;i<=m;++i)
scanf("%d%d",&A.x[i],&A.y[i]); for (i=1;i<=m;++i)
scanf("%d%d",&B.x[i],&B.y[i]); printf("%d\n",(n-1<<1)-Cross());
}
return 0;
}
H (Challenge) Maximizing LIS
JB Challenge写了好久的退火TMD没分233
最后还是靠着乱打的点东西拿了\(0.004\)分的好成绩
Postscript
我实在是太弱了……
Codechef October Challenge 2019 Division 1的更多相关文章
- Codechef November Challenge 2019 Division 1
Preface 这场CC好难的说,后面的都不会做QAQ 还因为不会三进制位运算卷积被曲明姐姐欺负了,我真是太菜了QAQ PS:最后还是狗上了六星的说,期待两(三)场之内可以上七星 Physical E ...
- Codechef September Challenge 2019 Division 2
Preface 这确实应该是我打过的比较水的CC了(其实就打过两场) 但由于我太弱了打的都是Div2,所以会认为上一场更简单,其实上一场Div的数据结构是真的毒 好了废话不多说快速地讲一下 A Eas ...
- Codechef August Challenge 2019 Division 2
Preface 老年菜鸡终于开始打CC了,由于他太弱了所以只能打Div2 因为台风的原因challenge并没有写,所以水了个Rank7 A Football SB模拟题不解释 #include< ...
- Codechef April Challenge 2019 Division 2
Maximum Remaining 题意:给n个数,取出两个数$a_{i}$,$a_{j}$,求$a_{i}\% a_{j}$取模的最大值 直接排个序,第二大(严格的第二大)模第一大就是答案了. #i ...
- CodeChef November Challenge 2019 Division 1题解
传送门 AFO前的最后一场CC了--好好打吧-- \(SIMGAM\) 偶数行的必定两人平分,所以只要抢奇数行中间那个就行了 这题怎么被爆破了 //quming #include<bits/st ...
- Codechef July Challenge 2019 Division 1题解
题面 \(CIRMERGE\) 破环成链搞个裸的区间\(dp\)就行了 //quming #include<bits/stdc++.h> #define R register #defin ...
- CodeChef October Lunchtime 2019 Division 2
HIT: Khaled in HIT 题目描述 Khaled 教练是 HIT(Hag Institute of Technology)一位名师.但是,他有一些困扰. 最近,Khaled 教练正在教一门 ...
- Codechef April Challenge 2019 游记
Codechef April Challenge 2019 游记 Subtree Removal 题目大意: 一棵\(n(n\le10^5)\)个结点的有根树,每个结点有一个权值\(w_i(|w_i\ ...
- Codechef October Challenge 2018 游记
Codechef October Challenge 2018 游记 CHSERVE - Chef and Serves 题目大意: 乒乓球比赛中,双方每累计得两分就会交换一次发球权. 不过,大厨和小 ...
随机推荐
- TimeSpan的用法
TimeSpan的属性和方法: 下面的列表涵盖了其中的一部分: 属性: Add:与另一个TimeSpan值相加. Days: 返回用天数计算的TimeSpan值.Hours: 返回用小时计算的Time ...
- 如何在Oracle 12C中Drop/Truncate多个分区 (Doc ID 1482264.1)
How to Drop/Truncate Multiple Partitions in Oracle 12C (Doc ID 1482264.1) APPLIES TO: Oracle Databas ...
- go 语言 搭建 图片上传 服务器
工具: LiteIDE 配置: 代码:list.html <!doctype html> <html> <head> <meta charset=" ...
- python-参数化-(2)(数据库判断是否存在并返回满足条件的数据)
1.根据python-参数化-(1),生成的数据号码 在数据库查询后判断是否存在若不存在返回手机号码,若存在返回该手机号码对应数据的信息,未封装成类或函数上代码 import pymysqlconn= ...
- JS 正则中环视(断言)应用 -- 数字千分符
介绍一下顺序环视 (?=...) 和逆序环视 (?<=...) 方便不想看长文的人,如果在支持 ES2018 的环境中整数可以这样使用: String(12345678).replace(/(? ...
- Centos7下Redis设置开机自启动服务
有个同事说重启了服务器没有自启动redis,我看了一下,是以前手动编译安装的模式,没有配置开机启动的服务 这边做个笔记记录一下redis如何设置编译安装模式的开机自启动. 第一种方法: 1.编写red ...
- 使用VBA从工作表中读图片,以及给工作表中写文件
因为工作的原因,需要用到VBA,碰到读图片和写图片: Sub Macro01() '从工作表中保存图片 Application.ScreenUpdating = False Dim pth, shp, ...
- SpringCloud微服务(05):Zuul组件,实现路由网关控制
本文源码:GitHub·点这里 || GitEE·点这里 一.Zuul组件简介 1.基础概念 Zuul 网关主要提供动态路由,监控,弹性,安全管控等功能.在分布式的微服务系统中,系统被拆为了多个微服务 ...
- C#斐波那契数列求法(比较阶乘和循环所用时间)
using System; namespace ConsoleApp3 { class Program { static void Main(string[] args) { Console.Writ ...
- docker: manifest for elasticsearch:latest not found
今天在docker安装es出现坑,是这样. 使用: docker pull elasticsearch 提示:manifest for elasticsearch:latest not found如图 ...