博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
AtCoder Grand Contest 030题解
阅读量:7092 次
发布时间:2019-06-28

本文共 6369 字,大约阅读时间需要 21 分钟。

第一次套刷AtCoder

体验良好


cout<

难度跨度有点大啊

可以证明当第一次转向之后,接下来每次的方向都和前一次相反

因为转向后再往相同方向走一定不如初始就往该方向走然后转两次向

枚举初始往哪个方向走以及走几步,前缀和优化即可

#include
#include
#include
#include
#include
#include
#include
#include
#define rt register int#define ll long longusing namespace std;inline ll read(){ ll x=0;char zf=1;char ch=getchar(); while(ch!='-'&&!isdigit(ch))ch=getchar(); if(ch=='-')zf=-1,ch=getchar(); while(isdigit(ch))x=x*10+ch-'0',ch=getchar();return x*zf;}void write(ll y){ if(y<0)putchar('-'),y=-y;if(y>9)write(y/10);putchar(y%10+48);}void writeln(const ll y){write(y);putchar('\n');}int k,m,n,x,y,z,cnt,ans;ll ret;int a[200010];ll hz[200010],qz[200010],qzh[200010];void calc(){ for(rt i=n-1;i>=1;i--)hz[i]=hz[i+1]+2ll*(n-i)*a[i]; qz[1]=qzh[1]=a[1]; for(rt i=2;i<=n;i++)qz[i]=qz[i-1]+(2ll*i-1)*a[i],qzh[i]=qzh[i-1]+a[i]; ll ans=0; for(rt i=1;i<=n;i++){ ans+=a[i];int md=i+n>>1; ret=max(ret,ans-hz[md+1]-(qz[md]-qz[i]-(qzh[md]-qzh[i])*2ll*i)+qzh[n]*(n-i-1)); }}int main(){ int L=read();n=read();a[++n]=L; for(rt i=1;i
=2;i--)a[i]-=a[i-1]; calc();reverse(a+1,a+n+1);calc(); cout<

清真构造题

若$ k\leq n$显然可以构一个$ k*k$的正方形,第$ i$行全填$ i$即可

当$ n < k \leq 2n$时,尝试从斜向入手

发现每个斜行可以交错填写数字,这样能填写的数字就能达到$ 2n$级别了

#include
#include
#include
#include
#include
#include
#include
#include
#define p 1000000007#define inv2 500000004#define rt register int#define ll long longusing namespace std;inline ll read(){ ll x=0;char zf=1;char ch=getchar(); while(ch!='-'&&!isdigit(ch))ch=getchar(); if(ch=='-')zf=-1,ch=getchar(); while(isdigit(ch))x=x*10+ch-'0',ch=getchar();return x*zf;}void write(ll y){ if(y<0)putchar('-'),y=-y;if(y>9)write(y/10);putchar(y%10+48);}void writeln(const ll y){write(y);putchar('\n');}int k,m,n,x,y,z,cnt,ans[505][505];int main(){ k=read(); if(k<=500){ writeln(k); for(rt i=1;i<=k;i++)for(rt j=1;j<=k;j++)cout<
<<" \n"[j==k]; return 0; } writeln(n=500); for(rt i=1;i<=n;i++){ ans[1][i]=i; for(rt x=n,y=i%n+1;x!=1;x--,y=y%n+1)ans[x][y]=i; } for(rt i=n+1;i<=k;i++){ if(i+i&1)ans[1][i]=i; for(rt x=n,y=i%n+1;x!=1;x--,y=y%n+1)if(i+y&1)ans[x][y]=i; } for(rt i=1;i<=n;i++)for(rt j=1;j<=n;j++)cout<
<<" \n"[j==n]; return 0;}

比B和C都清真多了...

设$ f[i][j][k]$表示经过$ i$次操作,$ a_j>a_k$的方案数

容易发现每次操作只对$ O(n)$级别的状态进行了非乘2的修改,其他都只是继承状态然后$ *2$

不妨把状态改成经过$ i$次操作,每次操作有$ 50\%$概率交换两个数,求逆序对的期望

滚动数组之后可以$ O(n^2)$解决转移,最后乘上$ 2^q$即可

#include
#include
#include
#include
#include
#include
#include
#include
#define p 1000000007#define inv2 500000004#define rt register int#define ll long longusing namespace std;inline ll read(){ ll x=0;char zf=1;char ch=getchar(); while(ch!='-'&&!isdigit(ch))ch=getchar(); if(ch=='-')zf=-1,ch=getchar(); while(isdigit(ch))x=x*10+ch-'0',ch=getchar();return x*zf;}void write(ll y){ if(y<0)putchar('-'),y=-y;if(y>9)write(y/10);putchar(y%10+48);}void writeln(const ll y){write(y);putchar('\n');}int k,m,n,x,y,z,cnt,ans;int f[3010][3010],g[3010][3010],a[3010];int main(){ n=read();m=read(); for(rt i=1;i<=n;i++)a[i]=read(); for(rt i=1;i<=n;i++) for(rt j=1;j<=n;j++)if(a[i]>a[j])f[i][j]=1; for(rt i=1;i<=m;i++){ x=read();y=read(); for(rt j=1;j<=n;j++)g[x][j]=f[x][j],g[j][x]=f[j][x],g[y][j]=f[y][j],g[j][y]=f[j][y]; f[x][y]=f[y][x]=1ll*(g[x][y]+g[y][x])*inv2%p; for(rt j=1;j<=n;j++){ const int v1=1ll*(g[x][j]+g[y][j])*inv2%p,v2=1ll*(g[j][x]+g[j][y])*inv2%p; if(j!=y&&j!=x)f[x][j]=v1,f[j][x]=v2; if(j!=x&&j!=y)f[y][j]=v1,f[j][y]=v2; } } int ans=0; for(rt i=1;i

神仙题!

我们在两个01串中的所有“01”结构之间连一条红线,“10”结构之间连一条蓝线

特判$ n \leq 2$之后发现两个01串等价的充要条件是这两个01串的红蓝线一一对应

发现每次改变非边界的数只会导致一条红/蓝线左移一位或右移一位

改变边界上的数可能会导致生成一条新的红/蓝线或使一条红/蓝线消失不见

容易发现移动不能使同一位置有多条线且线的颜色始终保持红蓝对应

我们可以把边界理解为有无限多条颜色交错的红蓝线

枚举上面的每条红线对应下面的每条红线,红线对答案的贡献就是每组相互对应的线的距离和 蓝线同理

数据范围允许暴力枚举对应$ O(n^2)$通过此题

#include
#include
#include
#include
#include
#include
#include
#include
#define rt register int#define ll long longusing namespace std;inline ll read(){ ll x=0;char zf=1;char ch=getchar(); while(ch!='-'&&!isdigit(ch))ch=getchar(); if(ch=='-')zf=-1,ch=getchar(); while(isdigit(ch))x=x*10+ch-'0',ch=getchar();return x*zf;}void write(ll y){ if(y<0)putchar('-'),y=-y;if(y>9)write(y/10);putchar(y%10+48);}void writeln(const ll y){write(y);putchar('\n');}int k,m,n,x,y,z,cnt,ans,ret;int a[100010],b[100010],t1,t2;char c[100010],s[100010];int calc(){ t1=t2=0; for(rt i=1;i<=n;i++)b[++t2]=0; for(rt i=1;i

正推推不出来的DP题启示我们弃疗倒着推

显然两个位置如果都不是$ -1$就可以扔掉

设有cnt组两个位置都是$ -1$则最终答案需要乘上$ cnt!$因为这些组可以任意交换位置

设$ f[i][j][k]$表示已经填了不小于$ i$的所有数,有$ j$个在序列中出现过的数没有被匹配,有$ k$个在原数列中未出现过的数没有被匹配

假设当前数在原序列出现过则可以匹配一个未出现过的数或自己变成一个未被匹配的数

不能匹配一个出现过的数的原因是假设相邻两个数都不是-1则要被扔掉

假设当前数在原序列中未出现过则可以匹配一个未出现过的数,一个出现过的数或自己成为未被匹配的数

注意如果匹配一个出现过的数有$ j$种匹配方式

直接$ O(n^3)DP$即可

#include
#include
#include
#include
#include
#include
#include
#include
#define p 1000000007#define rt register int#define ll long longusing namespace std;inline ll read(){ ll x=0;char zf=1;char ch=getchar(); while(ch!='-'&&!isdigit(ch))ch=getchar(); if(ch=='-')zf=-1,ch=getchar(); while(isdigit(ch))x=x*10+ch-'0',ch=getchar();return x*zf;}void write(ll y){ if(y<0)putchar('-'),y=-y;if(y>9)write(y/10);putchar(y%10+48);}void writeln(const ll y){write(y);putchar('\n');}int k,m,n,x,y,z,cnt,ans;int a[605];bool vis[605],nt[605];int q[605],t;int f[605][305][305];int main(){ n=read(); for(rt i=1;i<=2*n;i++){ a[i]=read();if(a[i]!=-1)vis[a[i]]=1; if(i&1^1){ if(a[i]==-1&&a[i-1]==-1)cnt++; if(a[i]!=-1&&a[i-1]!=-1)nt[a[i]]=nt[a[i-1]]=1; } } for(rt i=1;i<=2*n;i++)if(!nt[i])if(vis[i])q[++t]=1;else q[++t]=0;n=t; //q=1在原数列中 f[n][0][0]=1; for(rt i=n;i>=1;i--){ for(rt j=0;j<=n/2;j++) for(rt k=0;k<=n/2;k++)if(f[i][j][k]){ const int v=f[i][j][k]; if(q[i]){ (f[i-1][j+1][k]+=v)%=p; if(k)(f[i-1][j][k-1]+=v)%=p; }else { (f[i-1][j][k+1]+=v)%=p; if(k)(f[i-1][j][k-1]+=v)%=p; if(j)(f[i-1][j-1][k]+=1ll*v*j%p)%=p; } } } int ans=f[0][0][0]; for(rt i=2;i<=cnt;i++)ans=1ll*ans*i%p; cout<

 

转载于:https://www.cnblogs.com/DreamlessDreams/p/10478792.html

你可能感兴趣的文章
[LeetCode] Partition List 划分链表
查看>>
以Ajax方式显示Lotus Notes视图的javasript类库----NotesView2
查看>>
ylbtech-memorandum(备忘录)-数据库设计
查看>>
spm中头动绘图的理解,自带数据集
查看>>
PostgreSQL的 initdb 源代码分析之二十五
查看>>
I.MX6 su.c 测试
查看>>
Restful风格API接口开发springMVC篇
查看>>
车辆管理系统之继续自己的任务(五)
查看>>
谁该赋予一款产品灵魂?
查看>>
自我总结(八)- 新学期
查看>>
I.MX6 wm8962 0-001a: DC servo timed out
查看>>
ACM进阶计划
查看>>
Spring3 表达式语言(SpEL)介绍
查看>>
【Java学习笔记之七】java函数的语法规则总结
查看>>
5.23. msgpack
查看>>
【Java学习笔记之三十三】详解Java中try,catch,finally的用法及分析
查看>>
IE6 png图片实现半透明的方法
查看>>
程序猿的日常——Java基础之clone、序列化、字符串、数组
查看>>
Gulp Error: Cannot find module &#39;jshint/src/cli&#39;
查看>>
又见尾递归
查看>>