这场打的很烂,说明我对组合数学的掌握(二项式定理,以及递推式的思考方向)都不太好。而且,我做题的思路也很有问题。就是完全凭借灵感,自己没有脑子一样思路就被题目带跑了,根本跳不出来,看到题目也不会分析,直接找到一个缝隙就开始钻牛角尖。以后看到题目除了分析性质外,再把思路打开一些多考虑几种可能了再往下想(像我这种记性不好的最好在草稿纸上记一下)

当然比赛或者补题的时候,也暴露了平时学知识的一些问题,不会深入探究(就比如矩阵没有交换律为什么树上ddp线段树P_up()通常交换顺序乘起来是对的?)

[SNOI2017 DAY1]礼物

  • 题意:略
  • 思路:

    \(S_i=\sum_{i=1}^n A_i\)

    \(A_i=S_{i-1}+i^k\)

    \(S_i=2*S_{i-1}+i^k\)

    因为这个我也不会化成\(O(1)\)可以直接求的函数,所以看到\(m=10\)考虑最近学的矩阵快速幂(怎么搞出跟\(m\)有关的矩阵呢?)

    发现\(n^k=((n-1)+1)^k=\sum_{i=0}^k C_k^i*(n-1)^i\)

    然后发现其中的\((n-1)^i\)可以记录并用上面同样的公式递推的,因此按照\([f_i,i^k,i^{k-1}...i^1,i^0]\)这么构建矩阵,然后由倒着的杨辉三角构成系数矩阵。求矩阵快速幂即可。
  • code:
#include<bits/stdc++.h>
using namespace std;
const int N=105;
const int mod=1e9+7;
typedef long long ll;
ll C[N][N],inf=1e18;
int K;
struct matr {
ll z[13][13];
matr friend operator*(matr u,matr v) {
matr w;
for(int i=0;i<=K+1;i++) for(int j=0;j<=K+1;j++) {
ll tmp=0;
for(int k=0;k<=K+1;k++)tmp=(tmp+u.z[i][k]*v.z[k][j])%mod;
w.z[i][j]=tmp;
}
return w;
}
}a;
void init_C() {
C[0][0]=1;
for(int i=1;i<=K;i++) {
C[i][0]=1;
for(int j=1;j<=i;j++) {
C[i][j]=(C[i-1][j-1]+C[i-1][j])%mod;
}
}
}
void Build() {
for(int i=0;i<=K+1;i++)for(int j=0;j<=K+1;j++)a.z[i][j]=0;
a.z[0][0]=2;for(int j=K;j>=0;j--)a.z[0][K-j+1]=C[K][j];
for(int i=1;i<=K+1;i++) {
int k=K-i+1;
for(int j=0;j<=k;j++) a.z[i][K+1-j]=C[k][j];
} }
ll Ksm(ll b) {
matr mul=a;b--;
for(;b;b>>=1,a=a*a) {
if(b&1)mul=mul*a;
}
return mul.z[0][K+1];
}
ll ksm(ll w,ll b) {ll mul=1;w%=mod;for(;b;b>>=1,w=w*w%mod)if(b&1)mul=mul*w%mod;return mul;}
int main() {
ll n;scanf("%lld%d",&n,&K);
if(n==1) {printf("1");return 0;}
init_C();
Build();
ll res=Ksm(n-1);
// printf("%lld\n",res);
printf("%lld",(res+ksm(n,K))%mod);
return 0;
}

可变地图

  • 思路:

    为了不重不漏而且保证不会左右横跳。

    状态\(dp[i][j]\)由上层\(dp[i-1][k]\)转移时,保证按照\((i-1,k)->(i,k)-..->(i,j)\)方式走。

    然后递推系数矩阵很好造。

    ps.注意那个P_up是右边*左边
  • code:
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=2e5+5;
const int M=13;
const int mod=1e9+7;
int mp[N][M],n,m,K,ls[N],rs[N],Tcnt;
char ch[N][M];
struct matr {
ll z[10][10];
matr friend operator*(matr u,matr v) {
matr w;
for(int i=0;i<m;i++) for(int j=0;j<m;j++) {
ll tmp=0;for(int k=0;k<m;k++)tmp=(tmp+u.z[i][k]*v.z[k][j])%mod;
w.z[i][j]=tmp;
}
return w;
}
};
struct seg {int l,r;matr w;}T[N];
void Give(matr &tmp,int h) {
for(int i=0;i<m;i++)for(int j=0;j<m;j++)tmp.z[i][j]=0;
int pre=-1;
for(int j=0;j<m;j++) {
if(mp[h][j]==1) {
for(int x=pre+1;x<j;x++)for(int y=pre+1;y<j;y++) tmp.z[x][y]=1;
pre=j;
}
}
if(pre<m-1) {
for(int x=pre+1;x<m;x++)for(int y=pre+1;y<m;y++)tmp.z[x][y]=1;
}
}
void P_up(int x) {T[x].w=T[rs[x]].w*T[ls[x]].w;}
void Build(int &x,int l,int r) {
x=++Tcnt;T[x].l=l,T[x].r=r;
if(l==r) {Give(T[x].w,l);return;}
int mid=(l+r)>>1;
Build(ls[x],l,mid),Build(rs[x],mid+1,r);
P_up(x);
}
void Update(int x,int h) {
if(T[x].l==T[x].r) {Give(T[x].w,h);return;}
int mid=(T[x].l+T[x].r)>>1;
if(h<=mid)Update(ls[x],h);
else Update(rs[x],h);
P_up(x);
}
int main() {
scanf("%d%d%d",&n,&m,&K);
for(int i=1;i<=n;i++) {
scanf("%s",ch[i]);
for(int j=0;j<m;j++)mp[i][j]=ch[i][j]-'0';
}
int rt;if(n>=2)Build(rt,2,n);
for(int i=1;i<=K;i++) {
int p,x,y;scanf("%d%d%d",&p,&x,&y);y--;
if(p==1) {
mp[x][y]^=1;
if(x>1)Update(rt,x);
}
else {
x--;
if(mp[1][x]) {printf("0\n");}
else {
int l,r;l=r=x;
while(l>0&&!mp[1][l-1]) l--;
while(r<m-1&&!mp[1][r+1])r++;
if(n==1) {printf("%d\n",(y>=l&&y<=r));}
else {
matr res=T[rt].w;
// printf("![%d,%d](%d)\n",l,r,mp[1][r]);
ll ans=0;for(int j=l;j<=r;j++) ans=(ans+res.z[y][j])%mod;
printf("%lld\n",ans);
}
}
}
}
return 0;
}

最大连通子块和

  • 思路:不想写柿子了,很好推啦。就是更新g[]时删除并取max,这个可以用垃圾堆或者muitiset来维护。
  • code
#include<bits/stdc++.h>
using namespace std;
const int N=1e6+5;
const int M=2e5+5;
typedef long long ll;
int Tcnt,ls[N],rs[N],nxt[M<<1],to[M<<1],head[M],ecnt,top[M],sz[M],ed[M],son[M],fa[M],dfn[M],b[M],Time,rt[N];
priority_queue<ll> Q[M],_Q[M];
ll a[M],inf=1e17,f[M][2],g[M][2];
void add_edge(int u,int v) {nxt[++ecnt]=head[u];to[ecnt]=v;head[u]=ecnt;}
void gt_son(int u) {
sz[u]=1;
for(int i=head[u];i;i=nxt[i]) {
int v=to[i];if(v==fa[u])continue;
fa[v]=u;gt_son(v);sz[u]+=sz[v];
if(sz[son[u]]<sz[v]) son[u]=v;
}
}
void gt_top(int u,int Tp) {
top[u]=Tp;ed[Tp]=u;dfn[u]=++Time;b[Time]=u;
if(son[u])gt_top(son[u],Tp);
for(int i=head[u];i;i=nxt[i]) {
int v=to[i];if(v==fa[u]||v==son[u])continue;
gt_top(v,v);
}
}
void Dp(int u) {
g[u][1]=a[u];
for(int i=head[u];i;i=nxt[i]) {
int v=to[i];if(v==fa[u])continue;
Dp(v);
if(v==son[u])f[u][1]=max(f[v][1],0ll),f[u][0]=max(f[v][0],f[v][1]);
else g[u][1]+=max(f[v][1],0ll),g[u][0]=max(g[u][0],max(f[v][0],f[v][1])),Q[u].push(f[v][0]),Q[u].push(f[v][1]);
}
f[u][0]=max(f[u][0],g[u][0]),f[u][1]+=g[u][1];
// printf("%d: %lld %lld\n",u,f[u][0],f[u][1]);
}
struct matr {
ll z[3][3];
// matr() {for(int i=0;i<3;i++)for(int j=0;j<3;j++)z[i][j]=0;}
matr friend operator*(matr u,matr v) {
matr w;
for(int i=0;i<3;i++)for(int j=0;j<3;j++) {
ll mx=-inf;
for(int k=0;k<3;k++) mx=max(mx,u.z[i][k]+v.z[k][j]);
w.z[i][j]=mx;
}
return w;
}
};
void Print(matr x) {
puts("");
for(int i=0;i<3;i++){
for(int j=0;j<3;j++)printf("%lld ",x.z[i][j]);
puts("");
}
puts("");
}
struct seg {int l,r;matr w;}T[N];
void Give(matr &tmp,int x) {tmp.z[0][2]=g[x][0];tmp.z[1][1]=tmp.z[1][2]=g[x][1];}
void Nw(matr &tmp) {tmp.z[0][0]=tmp.z[0][1]=tmp.z[2][2]=0;tmp.z[1][0]=tmp.z[2][0]=tmp.z[2][1]=-inf;}
void P_up(int x) {T[x].w=T[ls[x]].w*T[rs[x]].w;}
void Build(int &x,int l,int r) {
x=++Tcnt;T[x].l=l,T[x].r=r;
if(l==r) {Nw(T[x].w);Give(T[x].w,b[l]);return;}
int mid=(l+r)>>1;
Build(ls[x],l,mid);Build(rs[x],mid+1,r);
P_up(x);
}
void Update(int x,int p,int y) {
if(T[x].l==T[x].r) {Give(T[x].w,y);return;}
int mid=(T[x].l+T[x].r)>>1;
if(p<=mid)Update(ls[x],p,y);
else Update(rs[x],p,y);
P_up(x);
}
matr Query(int x,int l,int r) {
if(l<=T[x].l&&T[x].r<=r) {return T[x].w;}
int mid=(T[x].l+T[x].r)>>1;bool f1=0;matr res;
if(l<=mid) {f1=1;res=Query(ls[x],l,r);}
if(r>mid) {
if(!f1)res=Query(rs[x],l,r);
else res=res*Query(rs[x],l,r);
}
return res;
}
struct node {ll _0,_1;};
node Ask(int u,int tp) {
matr res=Query(rt[tp],dfn[u],dfn[ed[tp]]);
// Print(res);
// printf("!%d [%d,%d]\n",rt[tp],dfn[u],dfn[ed[tp]]);
return (node){max(res.z[0][0],max(res.z[0][1],res.z[0][2])),max(res.z[1][0],max(res.z[1][1],res.z[1][2]))};
}
void change(int x,ll y) {
g[x][1]+=y-a[x];a[x]=y;
int v=x;
while(v) {
int u=top[v];
Update(rt[u],dfn[v],v);
node nw=Ask(u,u);
v=fa[u];
// printf("%d: %lld %lld\n",v,g[v][0],g[v][1]);
g[v][1]+=max(0ll,nw._1)-max(0ll,f[u][1]);
_Q[v].push(f[u][0]);_Q[v].push(f[u][1]);Q[v].push(nw._0);Q[v].push(nw._1);
while(!_Q[v].empty()&&_Q[v].top()==Q[v].top()) {_Q[v].pop();Q[v].pop();}
g[v][0]=Q[v].top();
f[u][0]=nw._0,f[u][1]=nw._1;
// printf("%d: %lld %lld\n",v,g[v][0],g[v][1]);
}
}
int main() {
// freopen("data.in","r",stdin);
// freopen("sb.out","w",stdout);
int n,m;scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++) scanf("%lld",&a[i]);
for(int i=1;i<n;i++) {int u,v;scanf("%d%d",&u,&v);add_edge(u,v),add_edge(v,u);}
gt_son(1);gt_top(1,1);Dp(1);
for(int i=1;i<=n;i++) {
int j=dfn[ed[b[i]]];
Build(rt[b[i]],i,j);i=j;
}
for(int i=1;i<=m;i++) {
char ch[3];int x;ll y;scanf("%s",ch);
if(ch[0]=='Q') {
scanf("%d",&x);
if(top[x]==x)printf("%lld\n",max(f[x][0],f[x][1]));
else {
node ans=Ask(x,top[x]);
printf("%lld\n",max(ans._0,ans._1));
}
}
else {
scanf("%d%lld",&x,&y);
change(x,y);
}
}
return 0;
}

2.26NK周赛的更多相关文章

  1. 周赛-KIDx's Pagination 分类: 比赛 2015-08-02 08:23 7人阅读 评论(0) 收藏

    KIDx's Pagination Time Limit: 2000/1000MS (Java/Others) Memory Limit: 128000/64000KB (Java/Others) S ...

  2. 2015浙江财经大学ACM有奖周赛(一) 题解报告

    2015浙江财经大学ACM有奖周赛(一) 题解报告 命题:丽丽&&黑鸡 这是命题者原话. 题目涉及的知识面比较广泛,有深度优先搜索.广度优先搜索.数学题.几何题.贪心算法.枚举.二进制 ...

  3. Leetcode 第133场周赛解题报告

    今天参加了leetcode的周赛,算法比赛,要求速度比较快.有思路就立马启动,不会纠结是否有更好的方法或代码可读性.只要在算法复杂度数量级内,基本上是怎么实现快速就怎么来了. 比赛时先看的第二题,一看 ...

  4. 牛客OI周赛9-提高组题目记录

    牛客OI周赛9-提高组题目记录 昨天晚上做了这一套比赛,觉得题目质量挺高,而且有一些非常有趣而且非常清奇的脑回路在里边,于是记录在此. T1: 扫雷 题目链接 设 \(f_i\) 表示扫到第 \(i\ ...

  5. codeforces 14A - Letter & codeforces 859B - Lazy Security Guard - [周赛水题]

    就像title说的,是昨天(2017/9/17)周赛的两道水题…… 题目链接:http://codeforces.com/problemset/problem/14/A time limit per ...

  6. 牛客OI周赛8-提高组A-用水填坑

    牛客OI周赛8-提高组A-用水填坑 题目 链接: https://ac.nowcoder.com/acm/contest/403/A 来源:牛客网 时间限制:C/C++ 2秒,其他语言4秒 空间限制: ...

  7. 计蒜客 28449.算个欧拉函数给大家助助兴-大数的因子个数 (HDU5649.DZY Loves Sorting) ( ACM训练联盟周赛 G)

    ACM训练联盟周赛 这一场有几个数据结构的题,但是自己太菜,不会树套树,带插入的区间第K小-替罪羊套函数式线段树, 先立个flag,BZOJ3065: 带插入区间K小值 计蒜客 Zeratul与Xor ...

  8. 周赛Problem 1108: 蛋糕(二分)

    1108: 蛋糕 Time Limit: 1 Sec  Memory Limit: 128 MB Submit: 17  Solved: 4 Description 杨神打代码打得有点疲倦,于是他想要 ...

  9. CSDN 轻松周赛赛题:能否被8整除

    轻松周赛赛题:能否被8整除 题目详情 给定一个非负整数,问能否重排它的全部数字,使得重排后的数能被8整除. 输入格式: 多组数据,每组数据是一个非负整数.非负整数的位数不超过10000位. 输出格式 ...

随机推荐

  1. Wepy-小程序踩坑记

    引言 用过原生开发的小程序也知道除了api 其他功能性的内容并不多对于需要做大型项目来说是比较难入手的,因此朋友推荐的wepy我就入坑鸟...这么一个跟vue的开发方式类似的框架,不过说起来跟vue类 ...

  2. CSS揭秘之《背景图案》

    网格 html { background: #58a; background-image: linear-gradient(white 2px, transparent 0), linear-grad ...

  3. String能变化吗?和StringBuffer的区别是什么

    [新手可忽略不影响继续学习]看 过上面例子的童鞋一定会觉得很奇怪,s = s + s1.charAt(i); 马克-to-win, s不是老在变化吗?其实s = "";时,虚拟机会 ...

  4. CentOS的安装以及IP地址(动态/静态)的配置

    啊!复试压力好大,跟好多学长聊完以后觉得自己更该好好努力了,一边好好准备复试科目,一边把之前忘掉的捡起来吧,加油! 1.安装的具体过程请参照这位博主写的,我觉得写的很详细,https://blog.c ...

  5. 微信小程序时间戳转为日期格式

    通常后台传递过来的都是时间戳,但是前台展示不能展示时间戳.就需要转化了. 功能说明: 微信小程序里,时间戳转化为日期格式,支持自定义. 拷贝至项目utils/utils.js中,并注意在js中声明下: ...

  6. vue行内动态添加样式或者动态添加类名

    还是记录一下吧(๑•ᴗ•๑) <li :style="{backgroundImage:`url(${item.pic})`}" @click="chooseVip ...

  7. Blazor组件自做四 : 使用JS隔离封装signature_pad签名组件

    运行截图 演示地址 响应式演示 感谢szimek写的棒棒的signature_pad.js项目, 来源: https://github.com/szimek/signature_pad 正式开始 1. ...

  8. YC-Framework版本更新:V1.0.6

    分布式微服务框架:YC-Framework版本更新V1.0.6!!! 本文主要内容: V1.0.6版本更新主要内容 V1.0.6版本更新主要内容介绍 一.V1.0.6版本更新主要内容 1.系统例子覆盖 ...

  9. Python Django项目日志查询系统

    该项目适合中小型公司日志查询工作.大型公司可以使用elk等.该系统其实就是调用了absible命令去查日志,然后把输出的信息输到页面查看. 日志查询系统 维护手册 作者:陈土锋 日期:2020年6月1 ...

  10. MongoDB 提供的工具

    MongoDB 提供的工具 官网 https://www.mongodb.com/ 工具 MongoDB 提供了一些工具,: MongoDB Compass: MongoDB数据库可视化工具(类似PL ...