牛客NOIP提高组(二)题解
心路历程
预计得分:100 + 40 + 30 = 170
实际得分:100 + 30 + 0 = 130
T2有一个部分分的数组没开够RE了。
T3好像是思路有点小问题。。 思路没问题,实现的时候一个细节没想过来。。
Sol
T1
直接把式子化开,发现都可以$O(1)$维护,做完了。。。
#include<cstdio>
#include<algorithm>
#include<vector>
#define LL long long
using namespace std;
const LL MAXN = 1e5 + ;
inline LL read() {
char c = getchar(); LL x = , f = ;
while(c < '' || c > '') {if(c == '-') f = -; c = getchar();}
while(c >= '' && c <= '') x = x * + c - '', c = getchar();
return x * f;
}
LL N, a[MAXN], sum, sump;
int main() {
N = read();
for(LL i = ; i <= N; i++) a[i] = read(), sum += a[i], sump += a[i] * a[i];
for(LL i = ; i <= N; i++) {
LL ans = (N - ) * (sump - a[i] * a[i]) - * (sum - a[i]) * (sum - a[i]) + (sum - a[i]) * (sum - a[i]);
if(i != N) printf("%lld ", ans);
else printf("%lld", ans);
}
return ;
}
T1
T2
好难啊,$30$分的枚举颜色dp应该比较好想把,$f[i][j]$表示第$i$个位置,填了$j$个颜色,然后先枚举一下$1$的颜色,前缀和优化一下,$O(n a_i^2)$
正解:
考虑容斥,令$f[i]$表示第$i$个位置的答案
什么都不考虑:$f[i] = f[i - 1] \times a[i]$
这时候会算重第$i$个位置和第$i - 1$个位置相同的情况,减去$f[i-2] * min(a[i], a[i - 1])$
然后会多减去$i - 2, i - 1, i$这三个位置相同的情况,加上$f[i - 3] * min(a[i], a[i -1], a[i - 2])$
不断容斥下去。
$f[i] = \sum_{j} (-1)^{i - j} f[i - j + 1] * min(a_{(i - j) \ to \ i})$
但是还有一个问题:这玩意儿是环形的,还需要考虑$1$和$i$不同的情况,。。。
这就很麻烦了,因为$1$和$i$的高度问题很难讨论。
我们直接把序列转一转,令$1$号位置的元素最小,这样$1$号元素不论取什么,$n$号位置一定会少一种取法
考虑如何优化这玩意儿,稍微化简一下,式子就变成了这样(负变正不影响奇偶性)
$f[i] = (-1)^i \sum_{j} (-1)^j f[i - j +1] \times min(a_{(i - j) \ to \ i})$
把$(-1)^j $和$f$看成一项,这东西显然有单调性。
考虑用单调栈去维护
具体做法是:考虑从$i$转移到$i+1$时答案的变化
一种情况是$a[i+1] > a[i]$这时候直接加上$i+1$的贡献即可
另一种情况是$a[i+1] < a[i]$,这时候前面的一些元素对答案的贡献会减小,用单调栈维护,找到第一个小于等于它的,减去这之间的位置的贡献即可。
时间复杂度:$O(n)$
代码中还用到了一个容斥。上面说的dp是不考虑$1$号位置与$i$号位置相同的情况
设$g_i$表示$1$与$i$拼成环相同时的方案数,稍微观察一下不难发现$g_i = f_{i - 1} - g_{i - 1}$。(把$1$和$i$看成相同的元素)
需要注意的是$g_2 = 0$,因此到达$2$时就需要停止
其实这个容斥方法也可以用来求该问题没有$a_i$限制时的通项公式。
代码较为高能,请谨慎查看。。
/* */
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<map>
#include<vector>
#include<set>
#include<queue>
#include<cmath>
//#include<ext/pb_ds/assoc_container.hpp>
//#include<ext/pb_ds/hash_policy.hpp>
#define Pair pair<LL, LL>
#define MP(x, y) make_pair(x, y)
#define fi first
#define se second
//#define LL long long
#define LL long long
#define ull unsigned long long
#define rg register
#define pt(x) printf("%d ", x);
using namespace std;
//using namespace __gnu_pbds;
const LL MAXN = 1e6 + , INF = 1e9 + , mod = 1e9 + ;
const double eps = 1e-;
inline LL read() {
char c = getchar(); LL x = , f = ;
while(c < '' || c > '') {if(c == '-') f = -; c = getchar();}
while(c >= '' && c <= '') x = x * + c - '', c = getchar();
return x * f;
}
LL N, a[MAXN], b[MAXN], f[MAXN], top;
Pair s[MAXN];
LL id(LL x) {
return x & ? (-) : ;
}
int main() {
N = read();
LL mn = INF, pos = , cnt = ;
for(LL i = ; i <= N; i++) {
a[i] = read();
if(a[i] < mn) mn = a[i], pos = i;
}
for(LL i = ; i <= N; i++) b[i] = a[pos], pos = pos % N + ;
memcpy(a, b, sizeof(b));
// for(LL i = 1; i <= N; i++) printf("%d ", b[i]);
f[] = -; /*for(LL i = 1; i <= N; i++) {
LL opt = 1, mn = INF;
for(LL j = i; j >= 1; j--) {
mn = min(a[j], mn);
f[i] = (f[i] + opt * f[j - 1] * mn + mod) % mod;
opt = (opt == 1 ? -1 : 1);
}
}*/
LL sum = ; s[++top] = MP(, );LL ans = ;
for(int i = ; i <= N; i++) {
LL now = ;
while(top && a[i] <= s[top].fi) {
sum = (sum - s[top].fi * s[top].se % mod) % mod;
now += s[top].se;
top--;
}
now = (now + f[i - ]) % mod;
//sum += id(i) * a[i] * now;
f[i] = sum + a[i] * now % mod; if(i & ) f[i] = -f[i];
f[i] = (f[i] + mod) % mod; if(i != )
if((N - i) & ) ans = (ans - f[i] + mod) % mod;
else ans = (ans + f[i]) % mod; if((i - ) & ) f[i] = -f[i];
f[i] = (f[i] + mod) % mod; s[++top] = MP(a[i], now);
(sum = sum + now * a[i] % mod + mod) %= mod;
} /*for(int i = N; i >= 2; i--)
if((N - i) & 1) ans = (ans - abs(f[i]) + mod) % mod;
else ans = (ans + abs(f[i])) % mod; */
//for(LL i = 1; i <= N; i++) printf("%I64d\n", f[i]); //puts("");
cout << (ans + mod) % mod;
return ;
}
/*
6
987 654 321 87 54 321 1 10
154 542 12 1 4354 2 12 121 2 45 4
3 5 1 2 4
4 4 4 4 3
3 3 3 2
2 3 1
4
*/
T2
T3
先考虑$m = 0$时。
定义$lowbit(i)$表示$i$的二进制下第一个为$1$的位置,很显然,如果我们把$lowbit(x)$相等的元素全都分给其中一个玩家这样一定是合法的。
每一个$i$能够贡献的数量为$2^{n - i}$。直接对$k$二进制拆分即可。考场上想到了,但是实现的时候傻乎乎的以为每次拆分的时候二进制位不能有重叠。。
$m \not = 0$的时候好像是个神仙dp,明天再看。。咕咕咕
牛客NOIP提高组(二)题解的更多相关文章
- 牛客NOIP提高组(三)题解
心路历程 预计得分:$30 + 0 + 0 = 30$ 实际得分:$0+0+0= 0$ T1算概率的时候没模爆long long了... A 我敢打赌这不是noip难度... 考虑算一个位置的概率,若 ...
- 牛客NOIP提高组R1 C保护(主席树)
题意 题目链接 Sol Orz lyq 我们可以把一支军队(u, v)拆分为两个(u, lca)和(v, lca) 考虑一个点x,什么时候军队对它有贡献,肯定是u或v在他的子树内,且lca在他的子树外 ...
- 牛客NOIP提高组R1 A中位数(二分)
题意 题目链接 Sol 很神仙的题目啊,考场上只会$n^2$的暴力.. 考虑直接二分一个$mid$,我们来判断最终答案是否可能大于$x$. 判断的时候记录一下前缀最小值即可, 设$s[i]$表示$1- ...
- 计蒜客 NOIP 提高组模拟竞赛第一试 补记
计蒜客 NOIP 提高组模拟竞赛第一试 补记 A. 广场车神 题目大意: 一个\(n\times m(n,m\le2000)\)的网格,初始时位于左下角的\((1,1)\)处,终点在右上角的\((n, ...
- 牛客CSP-S提高组赛前集训营1
牛客CSP-S提高组赛前集训营1 比赛链接 官方题解 before:T1观察+结论题,T2树形Dp,可以换根或up&down,T3正解妙,转化为图上问题.题目质量不错,但数据太水了~. A-仓 ...
- 18/9/16牛客网提高组Day2
牛客网提高组Day2 T1 方差 第一眼看就知道要打暴力啊,然而并没有想到去化简式子... 可能因为昨晚没睡好,今天上午困死 导致暴力打了一个半小时,还不对... #include <algor ...
- 18/9/9牛客网提高组Day1
牛客网提高组Day1 T1 中位数 这好像是主席树??听说过,不会啊... 最后只打了个暴力,可能是n2logn? 只过了前30% qwq #include<algorithm> #in ...
- 牛客网 提高组第8周 T1 染色
染色 链接: https://ac.nowcoder.com/acm/contest/176/A 来源:牛客网 题目描述 \(\tt{fizzydavid}\)和\(\tt{leo}\)有\(n\)个 ...
- 牛客网 提高组第8周 T2 推箱子 解题报告
推箱子 链接: https://ac.nowcoder.com/acm/contest/176/B 来源:牛客网 题目描述 在平面上有\(n\)个箱子,每个箱子都可以看成一个矩形,两条边都和坐标轴平行 ...
随机推荐
- C# 架构模式
单例模式 (Singleton) 单例讲的是当一个类被初次调用时,会产生一个类的实例, 而这个类的实例会贯穿程序的整个生命周期.单例提供了一个全局.唯一的实例. 步骤:1.让类自己创建一个实例:2.提 ...
- (六)编写基类BaseDao
在action中继承了ActionSupport和其它一些公共属性,如selectedRow等:可能以后还会产生更多公共的内容,所以应该把这些共有的抽取出来,放入到一个基本action中,我们命名为B ...
- 2、Python IDLE入门
转载:http://www.cnblogs.com/dsky/archive/2012/06/04/2535397.html 1.IDLE是Python软件包自带的一个集成开发环境,初学者可以利用它方 ...
- Javascript实现页面左边的菜单选中项高亮显示
在项目开发过程中,遇到一个问题 在一个模板页面中,Layout.cshtml,页面左边放了一个菜单项menu,每一项都是一个链接到一个新的页面.但所有页面都是用这个模板Layout.cshtml.需要 ...
- 2. DVWA亲测文件包含漏洞
Low级: 我们分别点击这几个file.php文件 仅仅是配置参数的变化: http://127.0.0.1/DVWA/vulnerabilities/fi/?page=file3.php 如 ...
- Django ORM 那些相关操作
Django ORM 那些相关操作 一般操作 必知必会13条 <> all(): #查询所有的结果 <> filter(**kwargs) # 它包含了与所给筛选条件相匹配的对 ...
- GTK学习笔记之Linux下Gtk环境搭建
下面介绍下Ubuntu 环境下具体的安装过程: 1.配置安装gcc/g++/gdb/make 等基本编程工具(必须装好) 刚装好的Ubuntu系统中已经有GCC了,但是这个GCC几乎什么文件都不能编译 ...
- PHP注释-----PHPDOC
用过IDE或看过其他源码的小伙伴们应该都见过类似下面这样的注释 /** * 递归获取所有游戏分类 * @param int $id * @return array */ 看得多了就大概知道了一些规 ...
- 动画重定向技术分析和Unity中的应用
http://www.jianshu.com/p/6e9ba1b9c99e 因为一些手游项目需要使用Unity引擎,但在动画部分需要使用重定向技术来实现动画复用,考虑到有些项目开发人员没有过这方面的经 ...
- 为HTML5添加新样式标签
为 HTML 添加新元素 该实例向 HTML 添加的新的元素,并为该元素定义样式,元素名为 <myHero> : 实例 <!DOCTYPE html> <html> ...