CF446 (Div. 1)简单题解
A .DZY Loves Sequences
pro:给定长度为N的序列,你最多可以改变一个数的值,问最长严格上升子序列长度。 N<1e5.
sol:分几种情况,一种的不改变; 一种是改变,然后接上一个; 一个是改变中间一个,接上两段,而且满足a[mid-1]<a[mid]<a[mid+1]
#include<bits/stdc++.h>
using namespace std;
#define rep(i,a,b) for(int i=a;i<=b;i++)
const int maxn=;
int a[maxn],L[maxn],R[maxn];
int main()
{
int N,ans=; scanf("%d",&N);
rep(i,,N) scanf("%d",&a[i]);
rep(i,,N) {
L[i]=;
if(i>&&a[i]>a[i-]) L[i]=L[i-]+;
}
for(int i=N;i>=;i--){
R[i]=;
if(i<N&&a[i]<a[i+]) R[i]=R[i+]+;
}
rep(i,,N) ans=max(ans,L[i]);
rep(i,,N) ans=max(ans,R[i]);
rep(i,,N-) {
if(a[i]<a[i+]-) ans=max(ans,L[i]+R[i+]+);
}
rep(i,,N-) ans=max(ans,L[i]+);
rep(i,,N) ans=max(ans,R[i]+);
printf("%d\n",ans);
return ;
}
B .DZY Loves Modification
pro:给定N*M有数字的矩阵 ,现在你可以进行K次操作,每次操作,你会选择一行或者一列,把其对应的数字和加到sum里,然后对应的每个数字减少P,问K次操作后最大的sum是多少。 N,M<1e3, K<1e6, p<1e2;
sol:关键在于想到,如果取的行数和列数次数确定了,那么他们相互影响的值是固定的。 然后就可以行列分开考虑了,我们考虑行,我们要取前K大,那么就是单调队列贪心取最大即可搞定。
#include<bits/stdc++.h>
#define rep(i,a,b) for(int i=a;i<=b;i++)
#define ll long long
using namespace std;
const int maxn=;
ll N,M,K,P,a[maxn][maxn],X[maxn],Y[maxn],t;
priority_queue<ll>A,B;
ll sumA[maxn*maxn],sumB[maxn*maxn],ans;
int main()
{
scanf("%lld%lld%lld%lld",&N,&M,&K,&P);
rep(i,,N) rep(j,,M) scanf("%lld",&a[i][j]);
rep(i,,N) rep(j,,M) X[i]=X[i]+a[i][j];
rep(i,,N) rep(j,,M) Y[j]=Y[j]+a[i][j];
rep(i,,N) A.push(X[i]);
rep(i,,M) B.push(Y[i]);
rep(i,,K){
t=A.top(); A.pop(); sumA[i]=t; A.push(t-M*P);
t=B.top(); B.pop(); sumB[i]=t; B.push(t-N*P);
}
rep(i,,K) sumA[i]+=sumA[i-],sumB[i]+=sumB[i-];
ans=sumB[K];
rep(i,,K){
ans=max(ans,sumA[i]+sumB[K-i]-1LL*i*(K-i)*P);
}
printf("%lld\n",ans);
return ;
}
C .DZY Loves Fibonacci Numbers
pro:给定一个大小为N的数组,现在进行Q次操作,1操作为区间加值,假如是区间[L,R],那么a[i]+=F[i-L+1],F是fib数列; 2操作为区间求和; N,Q<3e5;
sol:此题好像有几种方法,官方题解是用逆元blabla,感觉有点取巧。 然后线段树有两种解法。 一种是利用fib数列的性质,fib加fib还是有fib的性质,可以参考:
https://blog.csdn.net/johann_oier/article/details/49070067 。 但是这种方法的tag传递还是容易出错。
另外一种方法是利用fib数列的另外一个性质:Fn+m=Fn+1*Fm+Fn*Fm-1; 所以我们可以可以把相同的部分提出来,不相同的用前缀和操作。
即假如对区间[L,R]操作,对x增加F[x-L+1]=F[x+1]*F[-L]+F[x]*F[-1-L];而F[x+1]和F[x]我们可以预处理出来(代码里是A和B,而F[-L]我们不难倒推出来)
这种方法比较巧妙,这样救和普通lazy操作无异,所以常数很小。
#include<bits/stdc++.h>
#define rep(i,a,b) for(int i=a;i<=b;i++)
#define ll long long
using namespace std;
const int Mod=1e9+;
const int maxn=;
int sum[maxn],lazy1[maxn],lazy2[maxn],N;
int A[maxn],B[maxn],F[maxn],pre[maxn],fcy[maxn];
void MOD(int &x){ if(x>=Mod) x-=Mod;}
void pushup(int Now)
{
sum[Now]=(sum[Now<<]+sum[Now<<|])%Mod;
}
void build(int Now,int L,int R)
{
MOD(A[Now]=(pre[R+]-pre[L]+Mod));
MOD(B[Now]=(pre[R]-pre[L-]+Mod));
if(L==R){ scanf("%d",&sum[Now]); return;}
int Mid=(L+R)>>;
build(Now<<,L,Mid); build(Now<<|,Mid+,R);
pushup(Now);
}
void pushdown(int Now,int L,int R)
{
int Mid=(L+R)>>;
if(lazy1[Now]){
MOD(sum[Now<<]+=1LL*lazy1[Now]*A[Now<<]%Mod);
MOD(lazy1[Now<<]+=lazy1[Now]);
MOD(sum[Now<<|]+=1LL*lazy1[Now]*A[Now<<|]%Mod);
MOD(lazy1[Now<<|]+=lazy1[Now]);
lazy1[Now]=;
}
if(lazy2[Now]){
MOD(sum[Now<<]+=1LL*lazy2[Now]*B[Now<<]%Mod);
MOD(lazy2[Now<<]+=lazy2[Now]);
MOD(sum[Now<<|]+=1LL*lazy2[Now]*B[Now<<|]%Mod);
MOD(lazy2[Now<<|]+=lazy2[Now]);
lazy2[Now]=;
}
}
void update(int Now,int L,int R,int l,int r)
{
if(l<=L&&r>=R){
MOD(sum[Now]+=1LL*fcy[-l+N]*A[Now]%Mod);
MOD(sum[Now]+=1LL*fcy[-l+N]*B[Now]%Mod);
MOD(lazy1[Now]+=fcy[-l+N]);
MOD(lazy2[Now]+=fcy[-l+N]);
return;
}
pushdown(Now,L,R); int Mid=(L+R)>>;
if(l<=Mid) update(Now<<,L,Mid,l,r);
if(r>Mid) update(Now<<|,Mid+,R,l,r);
pushup(Now);
}
int query(int Now,int L,int R,int l,int r)
{
if(l<=L&&r>=R) return sum[Now];
int res=,Mid=(L+R)>>; pushdown(Now,L,R);
if(l<=Mid) (res+=query(Now<<,L,Mid,l,r))%=Mod;
if(r>Mid) (res+=query(Now<<|,Mid+,R,l,r))%=Mod;
pushup(Now); return res;
}
int main()
{
int M,opt,L,R;
scanf("%d%d",&N,&M);
F[]=; F[]=;
rep(i,,N+) MOD(F[i]=F[i-]+F[i-]);
rep(i,,N+) MOD(pre[i]=pre[i-]+F[i]);
fcy[N+]=; fcy[N]=; //对应负数的fib
for(int i=N-;i>=;i--) MOD(fcy[i]=fcy[i+]-fcy[i+]+Mod);
build(,,N);
rep(i,,M){
scanf("%d%d%d",&opt,&L,&R);
if(opt==) update(,,N,L,R);
else printf("%d\n",query(,,N,L,R));
}
return ;
}
D .DZY Loves Games
pro:给定N给点,有M条边的连通图,其中一些是黑点,一些是白点。 一开始在1号点,保证1号是白点,N号是黑点。 一开始有K滴血,每次走到一个黑点掉一滴血,每次在一个点会随机走到相邻的点,现在问第让他还有2滴血进入到N号点的概率。
sol:用高斯消元求出黑点之间走到的而不讲过其他黑点的概率,然后矩阵快速幂得到K-2次到N号点的概率。
(不会高斯消元,待补
。。。
CF446 (Div. 1)简单题解的更多相关文章
- CF449 (Div. 1简单题解)
A .Jzzhu and Chocolate pro:现在给定一个大小为N*M的巧克力,让你横着或者竖着切K刀,都是切的整数大小,而且不能切在相同的地方,求最大化其中最小的块. (N,M,K<1 ...
- CF444(Div. 1简单题解)
A .DZY Loves Physics 题意:给定带点权和边权的无向图,现在让你选一些点,使得 点权和/被选点对间的边权和 最大. 思路:不难证明,选择边和对应的两点是最优的. #include&l ...
- # Codeforces Round #529(Div.3)个人题解
Codeforces Round #529(Div.3)个人题解 前言: 闲来无事补了前天的cf,想着最近刷题有点点怠惰,就直接一场cf一场cf的刷算了,以后的题解也都会以每场的形式写出来 A. Re ...
- Codeforces Round #557 (Div. 1) 简要题解
Codeforces Round #557 (Div. 1) 简要题解 codeforces A. Hide and Seek 枚举起始位置\(a\),如果\(a\)未在序列中出现,则对答案有\(2\ ...
- Codeforces Round #538 (Div. 2) (A-E题解)
Codeforces Round #538 (Div. 2) 题目链接:https://codeforces.com/contest/1114 A. Got Any Grapes? 题意: 有三个人, ...
- Codeforces Round #531 (Div. 3) ABCDEF题解
Codeforces Round #531 (Div. 3) 题目总链接:https://codeforces.com/contest/1102 A. Integer Sequence Dividin ...
- Codeforces Round #499 (Div. 1)部分题解(B,C,D)
Codeforces Round #499 (Div. 1) 这场本来想和同学一起打\(\rm virtual\ contest\)的,结果有事耽搁了,之后又陆陆续续写了些,就综合起来发一篇题解. B ...
- Codeforces Round #353 (Div. 2) ABCDE 题解 python
Problems # Name A Infinite Sequence standard input/output 1 s, 256 MB x3509 B Restoring P ...
- Codeforces Beta Round #83 (Div. 1 Only)题解【ABCD】
Codeforces Beta Round #83 (Div. 1 Only) A. Dorm Water Supply 题意 给你一个n点m边的图,保证每个点的入度和出度最多为1 如果这个点入度为0 ...
随机推荐
- SpringBoot配置文件的加载位置
1.springboot启动会扫描以下位置的application.properties或者application.yml文件作为SpringBoot的默认配置文件 --file:/config/ - ...
- linux下/proc/diskstats文件详解
每一列的含义分别为: 第一列为 设备号 (number of issued reads. This is the total number of reads completed successfull ...
- HTTP、TCP、UDP的区别
TCP.UDP的区别 1.TCP面向连接(如打电话要先拨号建立连接);UDP是无连接的,即发送数据之前不需要建立连接 2.TCP提供可靠的服务.也就是说,通过TCP连接传送的数据,无差错,不丢失,不重 ...
- linux系统用户和组管理
用户和组管理 Linux是多用户多任务的网络操作系统,作为网络管理员,掌握用户的组的创建与管理至关重要. 学习要点: 了解用户和组的群的配置文件. 熟悉掌握Linux下用户的创建和维护管理. 熟悉掌握 ...
- sqlalchemy tree 树形分类 无限极分类的管理。预排序树,左右值树。sqlalchemy-mptt
简介: 无限极分类是一种比较常见的数据格式,生成组织结构,生成商品分类信息,权限管理当中的细节权限设置,都离不开无限极分类的管理. 常见的有链表式,即有一个Pid指向上级的ID,以此来设置结构.写的时 ...
- 7.5 C++基本序列式容器
参考:http://www.weixueyuan.net/view/6402.html 总结: vector可以理解为可以在两端插入.删除数据的数组,它提供了丰富的成员函数,用于操作数据. begin ...
- page指令import属性实例
<%@ page language="java" import="java.util.*" pageEncoding="utf-8"% ...
- 基于session做的权限控制
一直听说做权限将登陆信息放在session中,实际也说不太出个所以然来,幸运在工作当中接触到了对应的代码的copy. 实现思路: 类似于粗粒度的权限控制 将权限控制的文件按包分隔好,对应的url前缀也 ...
- shell脚本实例-实现监控tcp的链接状态另一种方式批量创建用户
Array实现TCP的链接状态 #!/usr/bin/bash declare -A status type=`ss -an | grep :80|awk '{print $2}'` for i in ...
- 某关于数位DP的一节课后的感受
题目 求给定区间[x,y]中满足下列条件的整数个数,这个数恰好等于k个互不相等的B的整数次幂之和 Input 15 20 2 2 Out 17 18 20 示例:17=24+20 18=24+21 2 ...