牛客网CSP-S提高组赛前集训营

标签(空格分隔): 题解 算法 模拟赛


题目 描述 做法
\(BSOJ6377\) 求由\(n\)长度的数组复制\(k\)次的数组里每个连续子序列出现数字种类的和 对每一种颜色计算贡献区间
\(BSOJ6378\) 求树上两条长度分别为\(p\),\(q\)不相交路径对数 换根背包\(dp~or~\)\(LCA\)+差分
\(BSOJ6379\)

\(T1\)

有一个长为\(n×k\)的数组,它是由长为\(n\)的数组\(A_1\),\(A_2\),...,\(A_n\)重复k次得到的。

定义这个数组的一个区间的权值为它里面不同的数的个数,现在,你需要求出对于这个数组的每个非空区间的权值之和。

答案对\(10^9+7\)取模。

注意到计算每一个区间的影响是很难的,因为我们能表示一个区间颜色种类数的方法是最快\(O(lenlog_2len)\)的

\(\text{HH}\)的项链

而这道题\(len\le 10^{14}\)让我们放弃

这又是一个套路了,既然我们不好直接求,那么拆分问题

给一个相似的例子

求\(a_1,a_2\cdots,a_n\)两两异或的和

肯定正着做不好做,但考虑到,这个问题在\(a_i\in\{0,2^k\}\)时就很好做

因此想到拆位

对于这道题也是一样,考虑计算每种颜色贡献的区间

仿佛也不好做,但正难则反,计算每种颜色不会贡献的区间很简单

那就是相邻的两个颜色间的所有区间

对\(n\)的序列我们可以轻易用一次扫描\(O(n)\)通过记录每个颜色上次出现的位置\(last_i\)利用组合数求出

但对\(n*k\)的呢

考虑有些部分重复求了

红色的被夹在区间中间的部分有\(K\)个

绿色蓝色各有\(1\)个

绿蓝拼在一起的有\(K-1\)个

因此我们只需要求\(n/2n\)的区间把色块拼起来就可以了

最后说明一下

长度\(\le len\)区间个数\(\frac{len(len+1)}{2}\)

#include<bits/stdc++.h>
#define re register
#define N 100001
#define INF 0x3f3f3f3f
#define mod 1000000007ll
using namespace std;
inline char nc(){
static char buf[1048576],*p1=buf,*p2=buf;
return p1==p2&&(p2=(p1=buf)+fread(buf,1,1048576,stdin),p1==p2)?EOF:*p1++;
}
#define getchar nc
template<typename _int>
inline void read(re _int& x){
re char opt;re _int flag=1,res=0;
while((opt=getchar())<'0'||opt>'9')if(opt=='-')flag=-1;
while(opt>='0'&&opt<='9'){res=(res<<3)+(res<<1)+opt-'0';opt=getchar();}
x=res*flag;
}
typedef long long ll;
int a[N<<1],pos[N],t[N],tot,l[N<<1];
ll ans,n,k;
inline ll f(re ll x){return x*(x+1)%mod*500000004ll%mod;}
inline void Read(void){
re int i;read(n);read(k);
for(i=1;i<=n;++i){read(a[i]);t[i]=a[i];}
sort(t+1,t+n+1);tot=unique(t+1,t+n+1)-(t+1);
for(i=1;i<=n;++i){a[i]=lower_bound(t+1,t+tot+1,a[i])-t;a[i+n]=a[i];}
}
inline void Solve(void){
re int i;re ll self,sum,len,left,right;
ans=f(1ll*n*k%mod)*tot%mod;
self=0;
for(i=1;i<=n;++i){
l[i]=pos[a[i]];pos[a[i]]=i;
if(l[i]+1==i||!l[i])continue;len=1ll*i-l[i]-1ll;
self=(self+f(len))%mod;
}
for(i=1;i<=tot;++i)pos[i]=0;
left=0;
for(i=1;i<=n;++i){
l[i]=pos[a[i]];pos[a[i]]=i;
if(l[i]||l[i]+1==i)continue;len=1ll*i-l[i]-1ll;
left=(left+(1ll*len*(len+1ll)>>1ll))%mod;
}
for(i=1;i<=tot;++i)pos[i]=n+1;
right=0;
for(i=n;i>=1;--i){
l[i]=pos[a[i]];pos[a[i]]=i;
if(l[i]!=n+1||l[i]-1==i)continue;len=1ll*l[i]-i-1ll;
right=(right+(1ll*len*(len+1ll)>>1ll))%mod;
}
for(i=1;i<=tot;++i)pos[i]=0;
sum=0;
for(i=1;i<=(n<<1);++i){
l[i]=pos[a[i]];pos[a[i]]=i;
if(l[i]+1==i)continue;len=1ll*i-l[i]-1ll;
sum=(sum+(1ll*len*(len+1ll)>>1ll))%mod;
}
sum=((sum-self*2ll%mod-left)%mod+mod)%mod;
ans=(((ans-1ll*k*self%mod+mod)%mod-sum*(k-1ll)%mod-left-right)%mod+mod)%mod;
printf("%lld\n",(ans%mod+mod)%mod);
}
int main(void){
Read();Solve();
return 0;
}

\(T2\)

\(有一棵n个点的树和两个整数p, q,求满足以下条件的四元组(a, b, c, d)的个数:\)

\(1.1≤a, b, c, d≤n。\)

\(2.点a到点b的经过的边数为p。\)

\(3.点c到点d的经过的边数为q。\)

\(4.不存在一个点,它既在点a到点b的路径上,又在点c到点d的路径上。\)

注意到不相交的情况太多(我考场上写换根写疯了)

首先考虑反求问题,不相交的路径数=所有路径数-相交路径数

考虑相交有哪些情况

我们把第三种颜色互换一下就变成了第二种

我们发现绿色的链总是过黑链的\(lca\)的

我们考虑枚举这个\(lca\)

他可以是两条只在子树内的链或者是一条子树内的链和一条从子树内(可以不进)到子树外的链

因此我们只需要算过一个点\(x\)子树内的链长为\(p/q\)方案数\(f_{x,p/q}\)以及从子树内(可以不进)到子树外的链长为\(p/q\)方案数\(g_{x,p/q}\)

考虑一条链拆成两条

设从\(x\)出发,子数内单链长为\(k\)的方案\(sf_{x,k}\)

则\(\displaystyle{sf_{x,k}=\sum_{y\in son_x}}sf_{y,k-1}\)

设从\(x\)出发,子数外单链长为\(k\)的方案\(gf_{x,k}\)

则\(\displaystyle{sg_{x,k}=sg_{fa_x,k-1}+sf_{fa_x,k-1}-sf_{x,k-2}}\)

就是来自父亲上面的,父亲下面不过自己的

合并的时候是类似背包的,我们把前面的儿子(\(sf'\))与\(y(sf)\)合并

因此\(\displaystyle{f_{x,p/q}=\sum_{k\in[0,p/q)}sf'_{x,k}\times sf_{x,p/q-k-1}}\)

\(g\)更简单

\(\displaystyle{g_{x,p/q}=\sum_{k\in[0,p/q]}sf_{x,k}\times sg_{x,p/q-k}}\)

\(T3\)

留坑

牛客网CSP-S提高组赛前集训营Round4的更多相关文章

  1. 牛客CSP-S提高组赛前集训营1

    牛客CSP-S提高组赛前集训营1 比赛链接 官方题解 before:T1观察+结论题,T2树形Dp,可以换根或up&down,T3正解妙,转化为图上问题.题目质量不错,但数据太水了~. A-仓 ...

  2. 牛客CSP-S提高组赛前集训营3

    A 货物收集 显然是一个二分答案的题. #include<iostream> #include<cstdio> #include<cstring> #include ...

  3. 牛客CSP-S提高组赛前集训营3 赛后总结

    货物收集 二分答案.复杂度\(O(n\log n)\). 货物分组 用费用提前计算的思想,考虑用一个新的箱子来装货物会发生什么. 显然费用会加上后面的所有货物的总重. \(60\)分的\(O(n^2) ...

  4. 牛客CSP-S提高组赛前集训营2 ———— 2019.10.31

    比赛链接 期望得分:100+20+20 实际得分:40+20+30 awa  cccc T1 :基于贪心的思路,然后开始爆搜(雾 那必然是会死的,好吧他就是死了 #include<iostrea ...

  5. 牛客CSP-S提高组赛前集训营1———2019.10.29 18:30 至 22:00

    期望得分:100+0+10 实际得分:40+0+0 考炸了... T1:题目链接 究竟为什么会这样,,, 仔细研读我的丑代码 发现... 枯辽.... #include<cstdio> # ...

  6. 牛客CSP-S提高组赛前集训营2 T2沙漠点列

    原题链接 算法不难,比赛的时候就和cyc大佬一起yy了正解,不过因为交的时候比较急(要回寝室惹),我有两数组开错大小直接爆到50,cyc大佬则只把文件输入关了一半,直接爆零(╯ ̄Д ̄)╯┻━┻ 要尽量 ...

  7. 20191029 牛客CSP-S提高组赛前集训营1

    前一个小时看这几道题感觉要爆零 A. 仓鼠的石子游戏 分析一下发现a[i]>1a[i]>1a[i]>1时后先手必输,a[i]=1a[i]=1a[i]=1时先手必赢 然后直接看1的个数 ...

  8. 牛客CSP-S提高组赛前集训营4 赛后总结

    复读数组 分成 3 种区间算答案: 一个块内的区间 两个块交界处,长度小于块长的区间 长度不小于块长的区间 对于第三种区间,容易发现每个区间的权值一样,只需要算出个数即可. 对于前两种空间,我的思路是 ...

  9. 牛客CSP-S提高组赛前集训营5 赛后总结

    A.无形的博弈 心理题. 答案为\(2^n\),可感性理解结论的正确性. #include<bits/stdc++.h> #define LL long long const LL Mod ...

随机推荐

  1. C++ 数组输出

    C++中输出数组数据分两种情况:字符型数组和非字符型数组 当定义变量为字符型数组时,采用cout<<数组名; 系统会将数组当作字符串来输出,如: ]={'}; cout << ...

  2. MarkDown的常规用法

    MarkDown的常规用法 标题 # 一级标题 ## 二级标题 ... ###### 六级标题 列表 第二级 - 和 空格 + 和 空额 * 和 空格 第三级 代码块 多行代码块 3个` 回车 单行代 ...

  3. 『正睿OI 2019SC Day6』

    动态规划 \(dp\)早就已经是经常用到的算法了,于是老师上课主要都在讲题.今天讲的主要是三类\(dp\):树形\(dp\),计数\(dp\),\(dp\)套\(dp\).其中计数\(dp\)是我很不 ...

  4. Java+Python+前端 学习资料大全 百度云盘

    Java架构师3大阶段 链接:https://pan.baidu.com/s/1DlXh33y5t4cZUmZH0cLvCw 提取码:5s76 2019前端架构阶段 链接:https://pan.ba ...

  5. 关于 返回数据类型 后 加& 的作用

    关于  返回数据类型 后 加& 的作用 请看以下图片 我的测试 //纯粹就是 为了 可作为 左值而存在的 方法 前 的返回值 int& ,如 int& Method(); // ...

  6. [转]解决ubuntu16.04 ‘E: 无法获得锁 /var/lib/dpkg/lock-frontend - open (11: 资源暂时不可用) ’ 问题

    当运行sudo apt-get install/update/其他命令时,会出现如下提示: E: 无法获得锁 /var/lib/dpkg/lock-frontend - open (11: 资源暂时不 ...

  7. 2019-08-01 jquery中常用方法

    1.attr()方法设置或返回被选元素的属性值 <html> <meta charset="utf-8"/> <head><title&g ...

  8. 阿里sentinel源码研究深入

    1. 阿里sentinel源码研究深入 1.1. 前言 昨天已经把sentinel成功部署到线上环境,可参考我上篇博文,该走的坑也都走了一遍,已经可以初步使用它的限流和降级功能,根据我目前的实践,限流 ...

  9. 医疗行业预测性产品的质量如何把关?MES系统帮大忙

    作为行业细分的医疗设备制造正在向工业4.0快速发展.它也可能仍然是世界上受监管最严格的行业之一,产品的个性化发展速度比其他行业更快. 在医疗设备行业中,由于需求或由于市场特定的规定,产品越来越多地定制 ...

  10. spring boot 的request.getServletContext().getRealPath路径获取问题

    默认情况下springboot中request.getServletContext().getRealPath 返回的是一个临时文件夹的地址 通过查看源代码 位置在 org.springframewo ...