【AtCoder】 ARC 100
link
C-Linear Approximation
给出\(N\)个数\(A_1,A_2,...,A_N\) ,求一个数\(d\),最小化\(\sum_{i=1}^N|A_i-(d+i)|\)
把\(A_i-i\)排个序,选取\(d=\)它们的中位数
#include<bits/stdc++.h>
#define ll long long
#define dbg1(x) cerr<<#x<<"="<<(x)<<" "
#define dbg2(x) cerr<<#x<<"="<<(x)<<"\n"
#define dbg3(x) cerr<<#x<<"\n"
using namespace std;
#define reg register
inline int read()
{
int x=0,f=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){x=(x<<3)+(x<<1)+ch-'0';ch=getchar();}
return x*f;
}
int a[200005];
ll ans;
int main()
{
int N=read();
reg int i;
for(i=1;i<=N;++i) a[i]=read()-i;
std::sort(a+1,a+N+1);
int mid=(N+1)/2;
for(i=1;i<=N;++i) ans+=abs(a[i]-a[mid]);
return 0*printf("%lld\n",ans);
}
D-Equal Cut
将数列分成\(4\)段,最小化“最大段的和-最小段的和”的绝对值
枚举第二个断点,然后第一个和第三个显然要满足两边的段和的差值最小
可以二分,但是发现选择的位置是单调的,可以\(O(N)\)完成
#include<bits/stdc++.h>
#define ll long long
#define dbg1(x) cerr<<#x<<"="<<(x)<<" "
#define dbg2(x) cerr<<#x<<"="<<(x)<<"\n"
#define dbg3(x) cerr<<#x<<"\n"
using namespace std;
#define reg register
inline ll read()
{
ll x=0,f=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){x=(x<<3)+(x<<1)+ch-'0';ch=getchar();}
return x*f;
}
const int MN=2e5+5;
ll a[MN],N,t1,t2,t3,ans;
ll cal(ll x,ll y,ll z)
{
ll _1=a[x],_2=a[y]-a[x],_3=a[z]-a[y],_4=a[N]-a[z];
return abs(max(max(_1,_2),max(_3,_4))-min(min(_1,_2),min(_3,_4)));
}
int main()
{
N=read();
reg int i;
for(i=1;i<=N;++i) a[i]=read()+a[i-1];
t1=1;t2=2;t3=3;ans=cal(1,2,3);
for(;t2<=N-2;++t2)
{
while(t1+1<t2&&abs(a[t2]-2*a[t1+1])<abs(a[t2]-2*a[t1]))++t1;
while(t3+1<N&&abs(a[N]-2*a[t3+1]+a[t2])<abs(a[N]-2*a[t3]+a[t2]))++t3;
ans=min(ans,cal(t1,t2,t3));
}
return 0*printf("%lld\n",ans);
}
E-Or Plus Max
给出\(2^N\)个数\(a_0,a_1,...a_{2^N-1}\),对于\(k=1,2,...,2^N-1\)
求出\(Max(a_i+a_j)\),其中\(0\le i<j\leq 2^N-1,i \ or \ j\leq k\)
用求子集和的方法(恰好能保证每个子集只出现了一次)求出子集内的最大和次大值
最后取当前缀最大值为当前集合的答案
/*8.20*/
#include<bits/stdc++.h>
#define ll long long
#define dbg1(x) cerr<<#x<<"="<<(x)<<" "
#define dbg2(x) cerr<<#x<<"="<<(x)<<"\n"
#define dbg3(x) cerr<<#x<<"\n"
using namespace std;
#define reg register
#define P pair<int,int>
#define mp make_pair
#define fi first
#define se second
inline int read()
{
int x=0,f=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){x=(x<<3)+(x<<1)+ch-'0';ch=getchar();}
return x*f;
}
const int MN=262200;
int N,S,ans;
P a[MN];
P Merge(P a,P b){if(a.fi<b.fi)swap(a,b);return mp(a.fi,max(a.se,b.fi));}
int main()
{
N=read();S=1<<N;
reg int i,j;
for(i=0;i<S;++i)a[i]=mp(read(),0);
for(j=0;j<N;++j)for(i=0;i<S;++i)if(i>>j&1)
a[i]=Merge(a[i],a[i^(1<<j)]);
for(i=1;i<S;++i)ans=max(ans,a[i].fi+a[i].se),printf("%d\n",ans);
return 0;
return 0;
}
F-Colorful Sequences
题意:定义一个长度为\(N\),字符集大小为\(K\)的序列是好的,当且仅当其中存在一个长度为\(K\)的子串满足\(1\)到\(K\)每个数恰好出现一次。给一个长度为\(M\)的序列\(A\),问在所有长度为\(N\)的好的序列里,\(A\)作为子串的出现次数的和。
序列\(A\)在所有序列中的出现次数是\((N-M+1)K^{N-M}\)
现在只要减去\(A\)在不好的序列中的出现次数就行了
\(A\)本身就是好的,那么不存在\(A\)在不好的序列中出现的情况
好的序列的好的子段可以利用\(A\)中全部的数(换言之:\(A\)中出现的数各不相同)
长度为\(M\)的出现的数均不相同的序列一共为\(A_K^M=\frac{K!}{(K-M)!}\),它们均等价
所以可以先求出所有上述序列的出现次数之和
问题变为:求出所有长度为\(N\)的不好序列中长度为\(M\)的“出现的数各不相同”的子串的总数量
这可以\(DP\)。
\(f_{i,j}\)表示所有长度为\(i\)的序列中,满足末尾最长长度为\(j\)的子串中元素各不相同的方案数
\(g_{i,j}\)表示\(f_{i,j}\)所表示的序列中,无重\(M\)长的子串一共又多少个
\[f_{i,j}=(K-j+1)f_{i-1,j-1}+\sum_{h=j}^{K-1}f_{i-1,h}
\\
g_{i,j}=(K-j+1)g_{i-1,j-1}+\sum_{h=j}^{K-1}g_{i-1,h}+[j\geq M]f_{i,j}
\]需要前缀和优化,复杂度\(O(N\times K)\)
好的序列的好的子段只能\(A\)的前缀/后缀的部分(换言之:\(A\)中存在相同的数)
分别对最长无重复前缀和最长无重复后缀进行\(Dp\)
然后枚举\(A\)串出现的位置进行计数
#include<bits/stdc++.h>
#define ll long long
#define dbg1(x) cerr<<#x<<"="<<(x)<<" "
#define dbg2(x) cerr<<#x<<"="<<(x)<<"\n"
#define dbg3(x) cerr<<#x<<"\n"
using namespace std;
#define reg register
inline int read()
{
int x=0,f=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){x=(x<<3)+(x<<1)+ch-'0';ch=getchar();}
return x*f;
}
const int MN=25005,MK=405,P=1e9+7;
int Mul(int x,int y){return 1ll*x*y%P;}
int Add(int x,int y){return (x+y)%P;}
int fp(int x,int y){int r=1;for(;y;y>>=1,x=Mul(x,x))if(y&1)r=Mul(r,x);return r;}
int N,K,M,ans,a[MN],fac[MN],inv[MN],fi[MN];
int sf[MN][MK],f[MN][MK],sg[MN][MK],g[MN][MK];
bool chk1()
{
static int ton[MK],num;
reg int i;
if(M<=K)return false;
num=0;
for(i=1;i<=K;++i)num+=!ton[a[i]]++;
if(num==K) return true;
for(i=K+1;i<=M;++i)
{
num-=!--ton[a[i-K]];
num+=!ton[a[i]]++;
if(num==K) return true;
}
return false;
}
int chk2()
{
static int ton[MK],num;
memset(ton,0,sizeof ton);
reg int i;num=0;
for(i=1;!ton[a[i]]&&i<=M;++i)num+=!ton[a[i]]++;
return num;
}
int main()
{
N=read(),K=read(),M=read();
reg int i,j,Z=max(N,K);
for(fac[0]=i=1;i<=Z;++i)fac[i]=Mul(fac[i-1],i);
for(inv[0]=inv[1]=1,i=2;i<=Z;++i)inv[i]=Mul(inv[P%i],(P-P/i));
for(fi[0]=i=1;i<=Z;++i)fi[i]=Mul(fi[i-1],inv[i]);
for(i=1;i<=M;++i) a[i]=read();
ans=Mul(N-M+1,fp(K,N-M));
if(chk1()){return 0*printf("%d\n",ans);}
f[0][0]=1;
for(i=1;i<=N;++i)for(j=1;j<K;++j)
{
f[i][j]=Add(Mul(f[i-1][j-1],K-j+1),Add(sf[i-1][K-1],P-sf[i-1][j-1]));
g[i][j]=Add(Mul(g[i-1][j-1],K-j+1),Add(sg[i-1][K-1],P-sg[i-1][j-1]));
if(j>=M)g[i][j]=Add(g[i][j],f[i][j]);
sf[i][j]=Add(sf[i][j-1],f[i][j]);
sg[i][j]=Add(sg[i][j-1],g[i][j]);
}
if(chk2()==M)
{
int tmp=Mul(sg[N][K-1],Mul(fac[K-M],fi[K]));
ans=Add(ans,P-tmp);
printf("%d\n",ans);
return 0;
}
else
{
int tmp=0,Mi,Ma,lm=chk2(),rm;
reverse(a+1,a+M+1);rm=chk2();
for(i=1;i<=N-M+1;++i)
{
int ii=i+lm-1,jj=N-i-M+1+rm,_1=0,_2=0;bool fl=ii==lm;
for(j=lm;j<K;++j) _1=Add(_1,Mul(Mul(f[ii][j],Mul(fac[K-j],fi[K])),Mul(fac[K-lm],fi[K-j])));
for(j=rm;j<K;++j) _2=Add(_2,Mul(Mul(f[jj][j],Mul(fac[K-j],fi[K])),Mul(fac[K-rm],fi[K-j])));
tmp=Add(tmp,Mul(_1,_2));
}
ans=Add(ans,P-tmp);
printf("%d\n",ans);
return 0;
}
}
Blog来自PaperCloud,未经允许,请勿转载,TKS!
【AtCoder】 ARC 100的更多相关文章
- 【AtCoder】ARC 081 E - Don't Be a Subsequence
[题意]给定长度为n(<=2*10^5)的字符串,求最短的字典序最小的非子序列字符串. http://arc081.contest.atcoder.jp/tasks/arc081_c [算法]字 ...
- 【Atcoder】ARC 080 F - Prime Flip
[算法]数论,二分图最大匹配 [题意]有无限张牌,给定n张面朝上的牌的坐标(N<=100),其它牌面朝下,每次操作可以选定一个>=3的素数p,并翻转连续p张牌,求最少操作次数使所有牌向下. ...
- 【Atcoder】ARC 080 E - Young Maids
[算法]数学+堆 [题意]给定n个数的排列,每次操作可以取两个数按序排在新序列的头部,求最小字典序. [题解] 转化为每次找字典序最小的两个数按序排在尾部,则p1和p2的每次选择都必须满足:p1在当前 ...
- 【AtCoder】 ARC 097
link C-K-th Substring 题意:找出已知串中第\(k\)大的子串,子串相同的不算 \(k\)好小啊,要怎么做啊 不是[Tjoi2015]弦论吗 算了,直接SAM吧 #include& ...
- 【AtCoder】 ARC 096
link C-Half and Half 题意:三种pizza,可以花\(A\)价钱买一个A-pizza,花\(B\)价钱买一个B-pizza,花\(C*2\)价钱买A-pizza和B-pizza各一 ...
- 【AtCoder】 ARC 098
link C-Attention 题意:一个字符队列,每个位置是\(W\)或\(E\),计算最小的修改数量,使得存在一个位置,它之前的都是\(E\),之后的都是\(F\) #include<bi ...
- 【AtCoder】 ARC 099
link C-Minimization 枚举覆盖\(1\)的区间,两边的次数直接算 #include<bits/stdc++.h> #define ll long long #define ...
- 【AtCoder】 ARC 101
link 搬来了曾经的题解 C-Candles 题意:数轴上有一些点,从原点开始移动到达这些点中的任意\(K\)个所需要的最短总路程 \(K\)个点必然是一个区间,枚举最左边的就行了 #include ...
- 【AtCoder】 ARC 102
link C-Triangular Relationship 发现要么全部是\(K\)的倍数,要么全部是模\(K\)余\(K/2,(K=2n)\) #include<bits/stdc++.h& ...
随机推荐
- 象棋中“车”的攻击范围_C#
如题: var a = new String[8,8]; int h, l; Console.WriteLine("输入车所在的行(0-7):"); h = int.Parse(C ...
- 世界上最大的软件注册表-----npm
npm 是什么? npm 为你和你的团队打开了连接整个 JavaScript 天才世界的一扇大门.它是世界上最大的软件注册表,每星期大约有 30 亿次的下载量,包含超过 600000 个 包(pack ...
- JavaScript的函数call和apply的区别、以及bind方法
1.call和apply的定义和区别 call和apply的作用一样,唯一不同的是:接受的参数不同. apply:方法能够劫持另一个对象的方法,继承另一个对象的属性. Funciton.apply(o ...
- linux系统crontab
一.cron 简介 在LINUX中,周期执行的任务一般由cron这个守护进程来处理[ps -ef|grep cron].cron读取一个或多个配置文件,这些配置文件中包含了命令行及其调用时间. cro ...
- Linux配置swap
根据自己的物理内存分配合适的swap大小 下面是合适的配置 物理内存 交换分区(swap) <=4G 至少2G 4-16G 至少4G 16G-64 至少8G 下面是操作步骤 1.首先查看我们的内 ...
- Cheat Engine 人造指针
打开游戏 查看内存区域 查看游戏当前使用的内存区域 下面这一段是游戏当前使用的内存区域,选择一片可以读写的内存区域 跳转到这片内存 查看是否有空余内存可以使用 使用空闲内存 我们选择0075DFD0开 ...
- Centos 7 中的ulimit -n 65535 对进程的文件句柄限制不生效??
今日闲来无事,就看群里大佬吹牛逼了,偶然一条技术疑问提出来了,神奇啊,作为广大老司机技术交流群体竟然还有这么深入的研究? 大佬问:这个文件句柄限制怎么设置了/etc/security/limits.c ...
- FFMPEG 命令行工具- ffmpeg
ffmpeg 简介 ffmpeg 用于转码的应用程序,命令格式: ffmpeg [options] [[infile options] -i infile]... {[outfile options] ...
- Socket网络编程-IO各种概念及多路复用
Socket网络编程-IO各种概念及多路复用 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.操作系统相关知识 1>.同步和异步 函数或方法被调用的时候,调用者是否得到最 ...
- django项目后台权限管理功能。
对后台管理员进行分角色,分类别管理,每个管理员登录账号后只显示自己负责的权限范围. 创建后台管理数据库 models.py文件内 # 管理员表 class Superuser(models.Model ...