A : 打表找规律
B : 数学期望
C : 拓扑排序+DP
D : 状压DP
E : 莫队+树状数组+卡常数
F : Unfinished

听说省选推迟了一个月,整个人都不好了。放假打了一场51Nod,感觉整个人更不好了。


A 1718 “多项式”

能出在第一题的多项式肯定是有奇技淫巧的,打表找了一发规律,发现它的循环节是-1,-2,-1,1,2,1,…

#include<cstdio>
using namespace std;
namespace runzhe2000
{long long n; int a[6] = {-1,-2,-1,1,2,1};void main(){scanf("%lld",&n);printf("%d",a[(n+4)%6]);}
}
int main()
{runzhe2000::main();
}

B 1756 谷歌的恐龙

设这一轮E1E_1是选完之后就死,这一轮的期望。E0E_0是选完之后活的期望。P=MNP=\frac{M}{N}

瞎JB推一下,答案 = E1+(1−P)∗E0PE_1+\frac{(1-P)*E_0}{P}

要开long double和输入优化- -

其实好像可以继续推下去的,然而不管啦……反正卡过去了

#include<cstdio>
#define N 10000005
#define getc() ((S == T) && (T = (S = B) + fread(B, 1, MaxBuff, stdin), S == T) ? 0 : *S++)
using namespace std;
namespace runzhe2000
{typedef long double ld;typedef double db;const int MaxBuff = 1 << 20;char B[MaxBuff], *S = B, *T = B;int read(){int r = 0; char c = getc();for(; c < '0' || c > '9'; c = getc());for(; c >='0' && c <='9'; r = r*10+c-'0', c = getc());return r;}int n, m, a[N];ld E0,E1, P;void main(){scanf("%d%d",&n,&m);for(int i = 1; i <= m; i++)  a[read()] = 1;for(int i = 0; i < n; i++){if(a[i]) E1 += (ld) i / m;else E0 += (ld) i / (n-m);}ld P = (ld)m / n;printf("%lf\n",(db)(E1+(1-P)*E0/P));}
}
int main()
{runzhe2000::main();
}

C 1815 调查任务

做得很虚的一道题。不知道我这个做法是不是对的,原来的代码被C题加强数据的第16个hack点卡了好久,多记了一个状态才过的。不知道会不会有别的数据能卡(如果有请务必告诉我^_^),毕竟这种图论题数据类型多种多样…

题意就是最大化路径的次大值。先缩强,记下强联通块内最大值和次大值。

记f[i]表示从S出发到i,能经过的最大值,这个直接DP就行了。

记g[i]表示从S出发到i,路径上经过的最大的次大值,也就是答案所求。考虑转移,大力分类讨论,设j能转移给i。

  1. 如果g[i]选择了点j及j之前的次大值,那直接从g[j]转移过来。
  2. 如果g[i]选择了点j及j之前的最大值,当且仅当i自身是路径最大值,这个用f[i]判一下。且此时那个被转移的最大值一定是f[j],(其实有反例,应该就是那个第16个点,也注意特判此时f[j]=f[i],需要多记h[j]表示除最大值以外的第二大,若f[j]=f[i]则从h[j]转移之类的)。
  3. 如果g[i]选择了i点自身的次大值或最大值,当且仅当f[i]大于i点自身的次大值或最大值,直接转移。

不保证上面口胡的东西是对的,因为调完代码之后我已经忘了我之前在想了什么了……

#include<cstdio>
#include<queue>
#include<cstring>
#define N 400005
#define M 2000005
#define cmin(u,v) ((u)>(v)?(u)=(v):0)
#define cmax(u,v) ((u)<(v)?(u)=(v):0)
using namespace std;
namespace runzhe2000
{int n, m, q, s, ecnt, a[N], last[N], bcnt, bel[N], mx[N], mx2[N], deg[N], tdeg[N], f[N], g[N], h[N];int timer, dfn[N], low[N], sta[N], insta[N], stacnt;struct edge{int next, to;}e[M<<1];struct pdge{int a, b;}pe[M];void addedge(int a, int b){e[++ecnt] = (edge){last[a], b};last[a] = ecnt;}void tarjan(int x){sta[++stacnt] = x; insta[x] = 1; dfn[x] = low[x] = ++timer;for(int i = last[x]; i; i = e[i].next){int y = e[i].to;if(!dfn[y]) {tarjan(y); cmin(low[x], low[y]);}else if(insta[y]) cmin(low[x], dfn[y]);}if(dfn[x] == low[x]){++bcnt; int y;do{y = sta[stacnt--];bel[y] = bcnt; insta[y] = 0;if(a[y] > mx[bcnt]) mx2[bcnt] = mx[bcnt], mx[bcnt] = a[y];else if(a[y] > mx2[bcnt] && a[y] != mx[bcnt]) mx2[bcnt] = a[y];}while(y != x);}}void dp(){{ // dp_mxmemcpy(tdeg, deg, sizeof(deg)); queue<int> q; q.push(bel[s]);for(; !q.empty(); ){int x = q.front(); q.pop(); cmax(f[x], mx[x]);for(int i = last[x]; i; i = e[i].next){int y = e[i].to; if(f[x] > f[y]){h[y] = f[y];f[y] = f[x];}else if(f[x] != f[y] && f[x] > h[y]) h[y] = f[x];if(!--tdeg[y]) q.push(y);}}}{ // dp_mx2memcpy(tdeg, deg, sizeof(deg)); queue<int> q; q.push(bel[s]);for(; !q.empty(); ){int x = q.front(); q.pop();if(mx[x] != f[x]) cmax(g[x], mx[x]);else cmax(g[x], mx2[x]);for(int i = last[x]; i; i = e[i].next){int y = e[i].to;cmax(g[y], g[x]);if(f[y] == mx[y] && f[x] != f[y]) cmax(g[y], f[x]);if(f[y] == mx[y] && h[x] != f[y]) cmax(g[y], h[x]);if(!--tdeg[y]) q.push(y);}}}}void main(){scanf("%d%d%d%d",&n,&m,&q,&s);for(int i = 1; i <= n; i++) scanf("%d",&a[i]);for(int i = 1, a, b; i <= m; i++){scanf("%d%d",&a,&b);addedge(a, b);pe[i] = (pdge){a, b};}tarjan(s); ecnt = 0;memset(last, 0, sizeof(last));for(int i = 1; i <= m; i++){if(bel[pe[i].a] != bel[pe[i].b] && bel[pe[i].a]){addedge(bel[pe[i].a], bel[pe[i].b]);deg[bel[pe[i].b]]++;}}deg[bel[s]] = 0;dp();for(int i = 1; i <= q; i++){int x; scanf("%d",&x);printf("%d ",dfn[x]?g[bel[x]]:-1);}}
}
int main()
{runzhe2000::main();
}

D 1683 最短路

写了比较长的一段题解,然后消失了,好气啊。那就再口胡一遍吧。n很小,对列状压,我们记f[i][j1][j2]...[jn]f[i][j_1][j_2]...[j_n] 表示到第i列的第1,2,…n行的最短路分别是j1,j2,…jn时的方案数,枚举下一列的状态转移。j1,j2…jn的状态数并不多,因为显然相邻两格最短路不超过1。j1,j2,…jn可以哈希起来。转移要先预处理,要不然可能会T。

#include<cstdio>
#include<algorithm>
#define N 7
#define M 105
#define H 250
using namespace std;
namespace runzhe2000
{const int INF = 1<<29;int n, m, mod, sta, tot, a[N], b[N], d[N], f[M][M+N][H], ans[M+N];struct trans{int to, up;}tr[H][1<<N];int packin(int *a){int ret = 0;for(int i = 2; i <= n; i++) ret = ret * 3 + (a[i] + 1);return ret;}int packout(int *a, int r){for(int i = n; i >= 2; i--) a[i] = r % 3 - 1, r /= 3;return r;}void main(){scanf("%d%d%d",&n,&m,&mod); sta = 1<<n;for(int i = 2; i <= n; i++) a[i] = 1; tot = packin(a);for(int i = 0; i <= tot; i++){packout(a, i);for(int k = 2; k <= n; k++) a[k] += a[k-1];for(int j = 0; j < sta; j++){for(int k = 1; k <= n; k++) b[k] = (j>>(k-1))&1;for(int k = 1; k <= n; k++) d[k] = a[k] + b[k];for(int k = 1; k <= n; k++){for(int h = k-1; h >= 1; h--) d[h] = min(d[h], d[h+1] + b[h]);for(int h = k+1; h <= n; h++) d[h] = min(d[h], d[h-1] + b[h]);}for(int k = n; k > 1; k--) d[k] -= d[k-1];tr[i][j] = (trans){packin(d), d[1]};}}for(int i = 0; i < sta; i++){for(int k = 1; k <= n; k++) b[k] = (i>>(k-1))&1;int s = packin(b);f[1][b[1]][s]++;}for(int i = 1; i < m; i++)for(int j = 0, jj = n+m; j < jj; j++)for(int k = 0; k <= tot; k++) if(f[i][j][k])for(int s = 0; s < sta; s++)(f[i+1][j+tr[k][s].up][tr[k][s].to] += f[i][j][k]) %= mod;for(int i = 0; i <= m; i++)for(int j = 0; j <= tot; j++){packout(a, j);for(int k = 2; k <= n; k++) a[k] += a[k-1];(ans[i+a[n]] += f[m][i][j]) %= mod;}for(int i = 0, ii = n+m; i < ii; i++) printf("%d\n",ans[i]);}
}
int main()
{runzhe2000::main();
}

E 1592 数列积

这是一个不知道正解的人的卡常数(log)的心酸历程

绝对值很麻烦,肯定要拆,那么就分开考虑ai<aja_i和ai>aja_i>a_j的。考虑到这个信息很难合并,想想莫队。

考虑加入一个元素之后发生了什么变化。设在区间[l,r][l,r]的尾部加了一个a[j]a[j]进来,其它位置的删/加类似。

我们先假设只有ai<aja_i 的情况,那答案就会增加∑ri=l(aj−ai)(j−i)\sum_{i=l}^r(a_j-a_i)(j-i),那我们可以维护四个信息()详见代码)来快速算出这个增量。对于ai>aja_i > a_j ,维护另一套信息即可。

然后我写了一个主席树,这样是O(nn√ log n)O(n\sqrt{n}\ log\ n)。卡了一个下午的常数,愣是没卡过去,当时整个人都不好了。

后来考虑O(nn√)O(n\sqrt{n})的做法,感觉可以上分块数据结构,也不知道对不对。

之后得知把主席树改成树状数组就能快很多。好吧,我naive了,改改改,拼命加优化。

再后来,我就也卡过去了…..

#include<cmath>
#include<ctime>
#include<cstdio>
#include<algorithm>
#define N 50005
#define lowbit(_i)  (_i&-_i)
#define R register
using namespace std;
namespace runzhe2000
{typedef unsigned long long ull;int read(){int r = 0; char c = getchar();for(; c < '0' || c > '9'; c = getchar());for(; c >='0' && c <='9'; r = r*10+c-'0', c = getchar());return r;}int n, S, qcnt, mx, a[N], block[N], ccnt;ull out[N];struct que{int l, r, id;bool operator < (const que &that) const {return block[l] != block[that.l] ? block[l] < block[that.l] : (block[l] & 1) ? r < that.r : that.r < r;}}q[N];struct BIT{ull t[N<<1];ull ask(R int x){R ull r = 0; for(; x; x -= lowbit(x)) r += t[x]; return r;}void mod(R int x, R ull v){for(; x <= mx; x += lowbit(x)) t[x] += v;}} tsum, tsum_i, tsum_a, tsum_1;ull add(int j){int pos = a[j];ull ret = 0, sum = tsum.ask(pos), sum_i = tsum_i.ask(pos), sum_a = tsum_a.ask(pos), sum_1 = tsum_1.ask(pos);ret += -sum+pos*sum_i+(j-n)*(sum_1*pos-sum_a);sum = tsum.ask(mx)-sum; sum_i = tsum_i.ask(mx)-sum_i; sum_a = tsum_a.ask(mx)-sum_a; sum_1 = tsum_1.ask(mx)-sum_1;ret -= -sum+pos*sum_i+(j-n)*(sum_1*pos-sum_a);tsum.mod(pos, (ull)(n-j)*pos);tsum_i.mod(pos, n-j);tsum_a.mod(pos, pos);tsum_1.mod(pos, 1);return ret;}ull del(int j){int pos = a[j];tsum.mod(pos, (ull)(j-n)*pos);tsum_i.mod(pos, -n+j);tsum_a.mod(pos, -pos);tsum_1.mod(pos, -1);ull ret = 0, sum = tsum.ask(pos), sum_i = tsum_i.ask(pos), sum_a = tsum_a.ask(pos), sum_1 = tsum_1.ask(pos);ret -= -sum+pos*sum_i+(j-n)*(sum_1*pos-sum_a);sum = tsum.ask(mx)-sum; sum_i = tsum_i.ask(mx)-sum_i; sum_a = tsum_a.ask(mx)-sum_a; sum_1 = tsum_1.ask(mx)-sum_1;ret += -sum+pos*sum_i+(j-n)*(sum_1*pos-sum_a);return ret;}void main(){n = read(); S = sqrt((double)n);for(int i = 1; i <= n; i++) a[i] = read(), block[i] = i % S == 1 ? block[i-1]+1 : block[i-1], mx < a[i] ? mx = a[i] : 0; mx++;qcnt = read();  for(int i = 1; i <= qcnt; i++) q[i].l = read(), q[i].r = read(), q[i].id = i;sort(q+1, q+1+qcnt); R int lef = 1, rig = 0, l, r; ull ans = 0; for(int i = 1; i <= qcnt; i++){l = q[i].l, r = q[i].r;for(; l < lef; lef--) ans -= add(lef-1);for(; rig < r; rig++) ans += add(rig+1);for(; lef < l; lef++) ans -= del(lef);for(; r < rig; rig--) ans += del(rig);out[q[i].id] = ans;}for(int i = 1; i <= qcnt; i++) printf("%llu\n",out[i]);}
}
int main()
{runzhe2000::main();
}

51Nod 算法马拉松23相关推荐

  1. 51nod 算法马拉松18 B 非010串 矩阵快速幂

    51nod 算法马拉松18 B 非010串 矩阵快速幂 非010串 基准时间限制:1 秒 空间限制:131072 KB 分值: 80 如果一个01字符串满足不存在010这样的子串,那么称它为非010串 ...

  2. 随便玩玩系列之一:SPOJ-RNG+51nod 算法马拉松17F+51nod 1034 骨牌覆盖v3

    先说说前面的SPOJ-RNG吧,题意就是给n个数,x1,x2,...,xn 每次可以生成[-x1,x1]范围的浮点数,把n次这种操作生成的数之和加起来,为s,求s在[A,B]内的概率 连续形的概率 假 ...

  3. 51nod 算法马拉松4 B递归(YY)

    递归 基准时间限制:1 秒 空间限制:131072 KB 分值: 80 函数f(n,m) { 若n=1或m=1返回a[n][m]; 返回f(n-1,m)异或f(n,m-1); } 读入2<=n, ...

  4. [51nod1847][算法马拉松23(飞越愚人节)F]奇怪的数学题

    前言 万年不写公开博客了,这次填个坑 题目相关 链接 题目大意 求∑i=1N∑j=1Nsgcd(i,j)k(mod232)\sum_{i=1}^N\sum_{j=1}^Nsgcd(i,j)^k\pmo ...

  5. 矩阵模板 51nod 算法马拉松分解问题

    题目:点击打开链接 一个矩阵乘法问题,(1+sqrt(2))的n次方! #include<bits/stdc++.h>using namespace std; #define maxn ( ...

  6. 【51NOD 1501】【51NOD 算法马拉松19】石头剪刀布威力加强版

    Description 小A和小B在玩石头剪刀布,他们每个人写出一个序列. 小A写出了n个数. 小B写出了m个数. 其中0代表石头,1代表剪刀,2代表布 0>1,1>2,2>0. 他 ...

  7. 51nod算法马拉松20 C、战忽局的手段

    战忽局的手段 基准时间限制:2 秒 空间限制:262144 KB 分值: 80 众所周知,有一个神秘的组织--战忽局,在暗中保护着我们.在局中任职的官员都有着极强的忽悠技巧,不只能用预言,还能用往事忽 ...

  8. 看图轻松理解数据结构与算法系列(2-3树)

    前言 推出一个新系列,<看图轻松理解数据结构和算法>,主要使用图片来描述常见的数据结构和算法,轻松阅读并理解掌握.本系列包括各种堆.各种队列.各种列表.各种树.各种图.各种排序等等几十篇的 ...

  9. 算法:2-3平衡树与B树的详细探讨

    2-3树是最简单的B树,B+树是B树的升级 B树的来源 为什么要有树 描述 1 - 多,N-M.层次等关系 从最根本的原因来看,使用树结构是为了提升整体的效率:插入.删除.查找(索引),尤其是索引操作 ...

最新文章

  1. java 反射机制_Java反射机制原理探究
  2. python运行速度和电脑配置有关系吗-学python最电脑配置有要求么
  3. 量子导航即将上路:实时更新,全局优化,不仅更快还能解决拥堵
  4. Angular @HostListener 装饰器的使用笔记
  5. 祝贺 在线文件管理系统 访问量 超过500
  6. 聊聊推荐系统的高阶特征交叉问题
  7. 菜鸟技术专家胡斌:技术架构的战略和战术原则
  8. 汉诺塔问题(信息学奥赛一本通-T1205)
  9. 数据库原理—DBS的物理组成和结构模式(五)
  10. win7下安装tomcat
  11. JavaScript执行机制-node事件循环
  12. OpenCV_Find Basis F-Matrix and computeCorrespondEpilines(获取一对图像的基础矩阵及对应极线)
  13. 【HDU5698】瞬间移动(杨辉三角+逆元)
  14. C#图片上一张下一张
  15. ServerGuide U盘安装Windows Server 2008 R2安装
  16. 如何给猫起一个英文名字
  17. 货币转换python代码_演示4:python与Tkinter的货币转换,4python,币值,含,tkinter
  18. ElasticSearch基础学习
  19. oracle 文本转数字,Oracle:需要将数值转换为文本并保留 - 已解决
  20. HashTab 2.08 简体中文版

热门文章

  1. 富文本编辑器Quill 介绍及在Vue中的使用方法
  2. android studio 中文乱码,字体优化解决之道
  3. spring data JPA中@Modifying 注解完成新增操作
  4. 在JSP中运用 Ajax
  5. 让Cnskype for business成为企业的好帮手
  6. OWASP DVWA XSS reflectedstored全系列
  7. Easyx 学习笔记
  8. 【loadrunner】【scorm学习】demo/test域上进行scorm脚本录制及回放成功脚本备份
  9. [leetcode]排列组合子集(python)
  10. 【只推荐一位Python大佬】 从程序员到创业者,再到自由职业