传送门

爆炸的比较厉害……果然还是菜啊……

\(A\)

我们强制一个点为\((0,0)\),那么设剩下两个点分别为\((a,b),(c,d)\),根据叉积可以计算出面积为\(ad-bc=S\),那么令\(ad\)略大于\(S\),然后对于\(bc\)暴力枚举一下就行了

ll S,p,a,b,c,d,t;
void init(){
if(p*p==S)return a=b=p,void();
a=b=p+1;
}
int main(){
cin>>S,p=sqrt(S);init(),t=a*b-S;
fp(i,1,1e9)if(t%i==0&&t/i<=1e9){c=i,d=t/i;break;}
printf("%lld %lld %lld %lld %lld %lld\n",0ll,0ll,a,c,d,b);
return 0;
}

\(B\)

我们考虑记录一个\(pos\),初始为\(1\),每一次找到序列中下一个和它元素值一样的位置,不管他们两个位置之间元素值长什么样子,他们两个之间肯定是要全被删掉的,然后令新的\(pos\)为那个一样的位置\(+1\)。因为\(pos\)的取值最多只有\(O(n)\)种,所以最多跑\(n\)次就可以找到循环节,找到循环节之后把\(k\)取个模就行了,剩下的就可以暴力跑了

//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;
typedef long long ll;
const int N=5e5+5;
int st[N],pk[N],a[N],nxt[N],las[N],xia[N],n,pos,top;ll k;
int main(){
scanf("%d%lld",&n,&k);
fp(i,1,n)scanf("%d",&a[i]),nxt[las[a[i]]]=i,las[a[i]]=i;
fp(i,1,n)nxt[las[a[i]]]=i,las[a[i]]=i;
fp(i,1,n-1)xia[i]=i+1;xia[n]=1;
st[++top]=1,pk[top]=1,pos=1;
do{
++top,pk[top]=pk[top-1]+(nxt[pos]<=pos)+(nxt[pos]==n);
st[top]=pos=xia[nxt[pos]];
}while(st[top]!=st[1]);
k-=(k-1)/(pk[top]-1)*(pk[top]-1);
R int j=1;
// fp(i,1,top)printf("%d %d %d\n",i,st[i],pk[i]);
// printf("%lld\n",k);
while(j<=top-1&&pk[j+1]<=k)++j;
// if(j==top-1)return 0;
// fp(i,st[j],n)printf("%d ",a[i]);
for(R int i=st[j];i<=n;++i){
if(nxt[i]>i)i=nxt[i];
else printf("%d ",a[i]);
}
return 0;
}

\(C\)

比赛的时候我简直就是个\(zz\)

首先,最终的序列合法,当且仅当

\(1.\max(a_i)\leq 2m\)

\(2.a_i\)为奇数的个数小于等于\(m\)个

那么我们只要枚举奇数的个数,把剩下的用隔板法分掉,就能计算出满足条件\(2\)的总的序列个数了。然后再减去所有最大值大于等于\(2m\)的序列,这个相当于把\(m-1\)个数分给\(n\)个人并把剩下的\(2m-1\)个数分给\(n\)个人中的任意一个,把这个方案数减掉就行了

//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=998244353;
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=3e6+5;
int fac[N],ifac[N],n,m,res,lim;
inline int C(R int n,R int m){return m>n?0:1ll*fac[n]*ifac[m]%P*ifac[n-m]%P;}
int main(){
scanf("%d%d",&n,&m);lim=m*3+n-1;
fac[0]=ifac[0]=1;fp(i,1,lim)fac[i]=mul(fac[i-1],i);
ifac[lim]=ksm(fac[lim],P-2);fd(i,lim-1,1)ifac[i]=mul(ifac[i+1],i+1);
fp(i,0,m)if((3*m-i)&1^1)upd(res,mul(C(n,i),C(((3*m-i)>>1)+n-1,n-1)));
res=dec(res,mul(n,C(m-1+n-1,n-1)));
printf("%d\n",res);
return 0;
}

\(D\)

思路的确很巧妙啊

为了方便起见以下从\(1\)开始标号

没有负环,意味着我们可以跑一个最短路,记\(p_i\)表示点\(i\)到\(1\)的最短距离,则对于剩下的每一条边\((i,j)\),都有\(p_i+w(i,j)\geq p_j\)

因为所有的\(0\)边都不能被删,所以必然有\(p_i\geq p_{i+1}\),那么我们定义\(q_i=p_i-p_{i+1}\),则\(q_i\geq 0\)

对于一条长度为\(1\)的边\((i,j)\),有\(p_i+1\geq p_j\),即\(q_j+q_{j+1}+...+q_{i-1}\leq 1\)

对于一条长度为\(-1\)的边\((i,j)\),有\(p_i-1\geq p_j\),即\(q_i+q_{i+1}+...+q_{j-1}\geq 1\)

不难发现,对于所有的\(q\),我们需要考虑的取值只有\(0\)和\(1\)

那么我们设\(f_{j,i}\)表示考虑完了\(q_1\)到\(q_i\),且上一个为\(1\)的是\(q_i\),再上一个为\(1\)的是\(q_j\),此时最小花费是多少。转移的时候,枚举下一个为\(1\)的位置\(q_k\),则需要删掉的边是,长度为\(1\),且满足\(r>k,i<l\leq j\)的\((r,l)\),或者长度为\(-1\),且满足\(j<l<r\leq k\)的\((l,r)\),这两个都可以用前缀和预处理,总的复杂度即为\(O(n^3)\),不过跑不满

//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;
typedef long long ll;
const int N=505;const ll inf=0x3f3f3f3f3f3f3f3f;
ll sa[N][N],sb[N][N],f[N][N];int n,a[N][N];
int main(){
scanf("%d",&n);
fp(i,1,n)fp(j,1,n)if(i!=j)scanf("%d",&a[i][j]);
fp(i,1,n)fp(j,i+1,n+1){
sa[i][j]=sa[i][j-1];
fp(k,i,j-1)sa[i][j]+=a[k][j];
}
fp(i,1,n)fd(j,n,i+1){
sb[i][j]=sb[i][j+1];
fp(k,1,i)sb[i][j]+=a[j][k];
}
memset(f,0x3f,sizeof(f));
f[0][0]=0;
fp(i,0,n)fp(j,i,n)if(f[i][j]<inf)
fp(k,j+1,n+1)cmin(f[j][k],f[i][j]+sa[j+1][k]+sb[j][k+1]-sb[i][k+1]);
R ll res=inf;
fp(i,0,n)cmin(res,f[i][n+1]);
printf("%lld\n",res);
return 0;
}

\(E\)

代码看起来好长啊不写了……

\(F\)

思路很妙啊……

首先容斥,那么我们现在就需要计算至少\(k\)个位置满足\(i^2+p_i^2<n^2\),且所有位置都满足\(i^2+p_i^2<(2n)^2\)的方案数

定义\(f(i)\)表示最小的\(a\)使得\(i^2+a^2\geq n\),\(g(i)\)表示最小的\(a\)使得\(i^2+a^2\geq (2n)^2+1\),那么假设我们现在已经选出了\(k\)个数使其满足\(i^2+p_i^2<n^2\),那么对于每一个数,它的取值范围都可以表示成\(p_i<h(i)\),其中\(h(i)=f(i)\)或者\(g(i)\)

然后我们把所有的\(h\)给\(sort\)一下,此时的方案数就是\(\prod\limits_{i=0}^{2n-1}(h_i-i)\)

然后我们考虑所有的\(f(i)(0\leq i<n)\)和\(g(i)(0\leq i<n)\)和\(g(i)(n\leq i<2n)\),分别记为\(A,B,C\)三类,不难发现\(B\)类永远大于\(A\)类和\(C\)类。且由于\(f\)和\(g\)都不降,我们把三类数合起来排个序,记\(fpos(i)\)表示排序后\(f(i)\)在数组中的位置,则有\(f(0)>f(1)>...>f(n-1)\)恒成立,对\(g\)也如此

那么现在问题转化成从\(0\)到\(n-1\)中,每一个数可以选择\(f(i)\)或者\(g(i)\),如果选了\(f(i)\)可以对\(k\)这一维\(+1\),对于一个选的方案贡献数为\(\prod\limits_{i=0}^{2n-1}(h_i-i)\),求总的贡献

那么\(dp\),设\(dp_{i,j}\)表示考虑完了\(f,g\)排序之后的前\(i\)个数,且选了\(f\)的有\(j\)个,此时的贡献总和。如果该位置是\(A\)类或\(C\)类我们可以直接计算出它前面有多少个数来计算贡献,如果是\(B\)类,我们可以根据此时的\(k\)来计算它的贡献

所以只要枚举\(k\)即可,复杂度\(O(n^3)\)

//quming
#include<bits/stdc++.h>
#define R register
#define fi first
#define se second
#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;
int P;
inline int up(R int x){return x<0?x+P:x;}
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;
}
typedef pair<int,int> pi;
const int N=505;
pi st[N];int c[N],a[N],dp[N],top,n,res;
inline int f(R int x,R int y){R int r=0;while(r<(n<<1)&&r*r+y*y<x*x)++r;return r;}
inline int g(R int x,R int y){R int r=0;while(r<(n<<1)&&r*r+y*y<=x*x)++r;return r;}
int main(){
scanf("%d%d",&n,&P);
fp(i,0,n-1)st[++top]=pi(f(n,i),-i);
fp(i,n,(n<<1)-1)st[++top]=pi(g(n<<1,i),1);
fp(i,0,n-1)c[i]=g(n<<1,i);
sort(st+1,st+1+top);
fp(k,0,n){
memset(dp,0,(k+1)<<2);
dp[0]=1;
int s1=0,s2=0;
fp(p,1,top)if(st[p].se==1){
fp(i,0,s2)dp[i]=mul(dp[i],up(st[p].fi-s1-i));
++s1;
}else{
fd(i,s2,0){
upd(dp[i+1],mul(dp[i],up(st[p].fi-s1-i)));
dp[i]=mul(dp[i],up(c[-st[p].se]-(n+k+s2-i)));
}
++s2;
}
upd(res,(k&1)?P-dp[k]:dp[k]);
}
printf("%d\n",res);
return 0;
}

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

  1. Atcoder Grand Contest 036 D - Negative Cycle

    Atcoder Grand Contest 036 D - Negative Cycle 解题思路 在某些情况下,给一张图加或删一些边要使图合法的题目要考虑到最短路的差分约束系统.这一题看似和最短路没 ...

  2. AtCoder Grand Contest 036 简要题解

    从这里开始 比赛目录 Problem A Triangle 考虑把三角形移到和坐标轴相交,即 然后能够用坐标比较简单地计算面积,简单构造一下就行了. Code #include <bits/st ...

  3. AtCoder Grand Contest 017 题解

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

  4. Atcoder Grand Contest 054 题解

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

  5. AtCoder Grand Contest 030题解

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

  6. AtCoder Grand Contest 031题解

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

  7. AtCoder Grand Contest 036 A-C

    目录 \(\bf A - Triangle\) \(\bf B - Do\ Not\ Duplicate\) \(\bf C - GP 2\) \(\bf D - Negative \ Cycle\) ...

  8. AtCoder Grand Contest 036

    Preface 这篇已经鸽了好久的说,AGC037都打完了才回来补所以题目可能都记不大清楚了,如有错误请指正 这场感觉难度远高于上一场,从D开始就不会了,E没写(看了题解都不会写),F就是抄曲明姐姐的 ...

  9. AtCoder Grand Contest 039 题解

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

随机推荐

  1. 【Java并发专题之一】Java内存模型

    一.计算机内存模型 针对计算机机器而言,操作系统.JVM程序等其他所有程序都需要遵循内存模型规范.1.CPU技术发展1.1 CPU缓存的出现CPU的发展快于内存条,CPU的运算速度越来越快,内存条的读 ...

  2. HTML连载20-并集选择器&兄弟选择器

    一.并集选择器 1.作用:给所有的选择器选中的标签设置属性. 2.格式: 选择器1,选择器2{ 属性:值: } 3.例如: .abc1,#abc2{ color:red; } .......省略代码. ...

  3. 卡尔曼滤波C++代码

    #include <ros/ros.h> #include <string> #include <stdlib.h> #include <iostream&g ...

  4. cap理论与分布式事务的解决方案

    现在很火的微服务架构所设计的系统是分布式系统.分布式系统有一个著名的CAP理论,即一个分布式系统要同时满足一致性(Consistency).可用性(Availablility)和分区容错(Partit ...

  5. .NET Core 学习笔记之 WebSocketsSample

    1. 服务端 代码如下: Program: using Microsoft.AspNetCore; using Microsoft.AspNetCore.Hosting; namespace WebS ...

  6. LocalDB 从2017更换到2014后一直显示连接不正确解决方案

    问题描述:LocalDB 版本混装后出现默认实例创建不成功 无法连接到 (LocalDB)\MSSQLLocalDB. ------------------------------其他信息: 在与 S ...

  7. C# - VS2019WinFrm桌面应用程序FtpClient实现

    前言 本篇主要记录:VS2019 WinFrm桌面应用程序实现简单的FtpClient,包含Ftp文件查看.上传和下载等功能. 准备工作 搭建WinFrm前台界面 添加必要的控件,这里主要应用到Gro ...

  8. centos下非yum方式安装docker环境

    1.下载docker源码包 docker官网地址: https://download.docker.com/linux/static/stable/ 选择.tgz的包下载,例如:https://dow ...

  9. UML与设计模式

    这个在大中华区不知道是否重视,反正我是接触的人中谈的少,除了想起大学有个博士级别的老师,给我们上课天天老拿着一本外文翻译的UML书外,可真要重视起来的. 加深一个单词,模式pattern,patter ...

  10. CTF必备技能丨Linux Pwn入门教程——格式化字符串漏洞

    Linux Pwn入门教程系列分享如约而至,本套课程是作者依据i春秋Pwn入门课程中的技术分类,并结合近几年赛事中出现的题目和文章整理出一份相对完整的Linux Pwn教程. 教程仅针对i386/am ...