【agc003E】Sequential operations on Sequence
Description
给你一个数串\(S\),一开始的时候\(S=\{1,2,3,...,n\}\),现在要对其进行\(m\)次操作,每次操作给定一个\(a\),具体方式为将\(S\)重复写很多很多很多次然后取前\(a\)个数作为新的\(S\),问最后得到的\(S\)中\(1\sim n\)每个数的出现次数
Solution
emmm想到了解法但是想用线段树解决原本暴力就可以解决的东西然后就凉了==
首先手玩一下小规模的数据,记当前\(S\)的长度为\(nowlen\),要变成的新的长度为\(x\),\(cnt[i]\)表示当前数字\(i\)出现的次数,分两种情况讨论一下:
1、如果说\(nowlen<=x\):那么所有的\(cnt[i]\)肯定都要\(*x/nowlen\),然后再加上余数的贡献(这部分比较复杂,先不展开说)
2、如果说\(nowlen>x\):那么会发现我们要先找到之前的某次操作使得那次操作之后\(S\)的长度\(<=x\),然后再回到1中的情况
也就是说,我们其实只关心长度不下降的操作,所以接下来提到的操作都是以最后一个操作结尾的不下降操作序列(记为\(st[i]\)好了)中的元素
现在我们着重思考一下那个余数的问题,考虑余数(记为\(rest\))部分的贡献其实就是\(S\)的前\(rest\)个数,那其实我们要做的就是查询某次操作之后\(S\)的前\(rest\)个数中每个数出现的次数,会发现这个其实就是。。原问题,那所以。。递归求解之类的。。?
我们考虑实现一个过程\(solve(x,l)\)表示在第\(x\)次操作之后,\(S\)前\(l\)位中每个数出现的次数(假装返回值是一个数组),记\(cnt[i]\)表示第\(i\)次操作之后\(S\)中每个数字的出现次数(其实就是一个二维数组啦==不过当然只是方便理解这么说,实际实现的时候并不需要开这么一个玩意)那么大概可以写出来一个\(solve(x,l)=l/st[x-1]*cnt[x-1]+solve(x-1,l\%st[x-1])\)
然后接下来就是一个比较重要的经典性质:一个数每次模不大于它的数,总共只能模\(log\)次
(没错反正我当时弱智了没有反应过来==)
所以至多递归\(log\)层(当\(l=0\)的时候自然就直接返回了嘛)
所以我们可以考虑暴力一点来处理这个东西(数据结构什么的是没有前途的qwq比如说一开始想了一个可持久化线段树==显然空间爆炸)
注意到根据上面那条。。递归式,我们可以知道\(cnt[i]\)可以被表示为至多\(log\)个带个系数的\(cnt[j](j<i)\)每次再加上一些不需要递归处理的余数的贡献(也就是当余数\(<=st[1]\)的时候,此时不需要再递归处理而是可以直接得到,因为肯定是对从\(1\)开始的连续的某一段的数字有贡献,或者更加笼统一点就是一个前缀)的和,所以我们考虑维护一个\(addtag\),\(\sum\limits_{i=1}^x addtag[i]\)表示处理到当前,数\(x\)的不需要递归处理的余数贡献,再维护一个\(multag[i]\)表示,用\(cnt[i]\)来表示\(cnt[m]\)(也就是最后的\(cnt\))时,前面需要乘的系数(其实如果再直白一点。。可以说\(addtag\)其实就相当于一个零头,当然这个说法不严谨),那么由于最开始的\(cnt\)是知道的(都是\(1\)),所以最后数字\(x\)的答案(如果不为\(0\)的话)就应该是\(multag[1]*1+\sum\limits_{i=1}^xaddtag[i]\)
最后就是实现问题了,其实就是正常每次把商乘上去就好了好像也没有什么特别要说的。。
mark:(貌似依旧是没有什么建设性的东西。。)把未知的转化成已知的。。?比如说就是把系数推出来然后用最开始的cnt来表示最后的cnt
mark:一个数每次模不大于它的数,总共只能模\(log\)次
代码大概长这个样子
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define ll long long
using namespace std;
const int N=1e5+10;
ll a[N];
ll ans[N],st[N],addtag[N],multag[N];
int n,m;
ll nowlen;
void prework(){
st[0]=0; a[0]=n;
for (int i=0;i<=m;++i){
while (st[0]&&st[st[0]]>a[i]) --st[0];
st[++st[0]]=a[i];
}
}
int get_pos(ll x,int r){
int l=1,mid,ret=r;
while (l<=r){
mid=l+r>>1;
if (st[mid]<=x) ret=mid,l=mid+1;
else r=mid-1;
}
return ret;
}
void solve(ll k,ll rest,int ed){
if (!rest) return;
if (rest<=st[1]){
addtag[1]+=k; addtag[rest+1]-=k;
return;
}
int pre=get_pos(rest,ed);
multag[pre]+=k*(rest/st[pre]);
solve(k,rest%st[pre],pre-1);
}
int main(){
#ifndef ONLINE_JUDGE
freopen("a.in","r",stdin);
#endif
ll rest,tmp,x;
scanf("%d%d",&n,&m);
nowlen=n;
for (int i=1;i<=m;++i) scanf("%lld",a+i);
prework();
multag[st[0]]=1;
for (int i=st[0];i>=2;--i){
tmp=st[i]/st[i-1];
rest=st[i]%st[i-1];
multag[i-1]+=multag[i]*tmp;
solve(multag[i],rest,i-1);
}
for (int i=1;i<=st[1];++i){
addtag[i]+=addtag[i-1];
printf("%lld\n",addtag[i]+multag[1]);
}
for (int i=st[1]+1;i<=n;++i) printf("0\n");
}
【agc003E】Sequential operations on Sequence的更多相关文章
- 【AGC003 E】Sequential operations on Sequence
Description 你有一个长度为 \(n\) 的序列,第 \(i\) 项为 \(i\). 有 \(m\) 次操作,每次操作给定一个 \(x\),你需要将序列无限循环后截取前 \(x\) 项,作为 ...
- 【BZOJ1345】[Baltic2007]序列问题Sequence 贪心+单调栈
[BZOJ1345][Baltic2007]序列问题Sequence Description 对于一个给定的序列a1, …, an,我们对它进行一个操作reduce(i),该操作将数列中的元素ai和a ...
- 【SPOJ】1182 Sorted bit sequence
[算法]数位DP [题解]动态规划 写了预处理函数却忘了调用是一种怎样的体验? #include<cstdio> #include<cstring> #include<a ...
- 【做题】agc003E - Sequential operations on Sequence——经典结论
题意:有一个序列,初始是从\(1\)到\(n\)的\(n\)个数.有\(q\)次操作,每次操作给出\(q_i\),把当前的序列重复无数遍,然后截取最前面的\(q_i\)个元素作为新序列.要求输出完成所 ...
- agc003E Sequential operations on Sequence
题意: 有一个数字串S,初始长度为n,是1 2 3 4 …… n. 有m次操作,每次操作给你一个正整数a[i],你先把S无穷重复,然后把前a[i]截取出来成为新的S. 求m次操作后,每个数字在S中出现 ...
- 线段树【CF620E】The Child and Sequence
Description At the children's day, the child came to Picks's house, and messed his house up. Picks w ...
- 题解【Codeforces438D】The Child and Sequence
题目描述 At the children's day, the child came to Picks's house, and messed his house up. Picks was angr ...
- 【转】Oracle数据库中Sequence的用法
在Oracle数据库中,sequence等同于序列号,每次取的时候sequence会自动增加,一般会作用于需要按序列号排序的地方. 1.Create Sequence (注释:你需要有CREATE S ...
- 【转】MySQL中增加sequence管理功能(模拟创建sequence)
1.oracel可以直接支持sequence,但是mysql不支持sequence,因此我们要通过模拟sequence的方法在mysql中创建sequence.模拟sequence的方法:项目场景:项 ...
随机推荐
- Git之hotfix热修复分支
1.假设你正在开发一个新功能, 需要新建一个new分支并切换: git checkout -b new 等价于 git branch new git checkout new 然后在这个new分支上已 ...
- Python接口测试实战3(下)- unittest测试框架
如有任何学习问题,可以添加作者微信:lockingfree 课程目录 Python接口测试实战1(上)- 接口测试理论 Python接口测试实战1(下)- 接口测试工具的使用 Python接口测试实战 ...
- python模块的作用和说明
Python模块 如果你从Python解释器退出并再次进入,之前的定义(函数和变量)都会丢失.因此,如果你想编写一个稍长些的程序,最好使用文本编辑器为解释器准备输入并将该文件作为输入运行.这被称作编写 ...
- python—退出ipython3的help()
退出ipython3的help() 组合键:ctrl+z
- 算法笔记(c++)--桶排序题目
算法笔记(c++)--桶排序 记得题目是排序,输入n个1-1000的数字然后去重然后排序. 桶排序没毛病 #include<iostream> using namespace std; i ...
- New Year_2019
新年目标 1. own的项目稳定高效,业务能满足业务方需求,功能质量超出业务方期待.2. 工作中成长,包括项目的需求管理,计划排期,整体的把控能力.3. 对公司的业务了解程度达到更高程度. 个人技能目 ...
- Amazon.com 购物 信用卡预售期
I understand and thanks for confirming. In this case, the $1.00 is not a charge. It is an authoriza ...
- 模仿qq列表信息滑动删除效果
这个效果的完成主要分为两个部分 自定义view作为listview的列表项 一个view里面包括 显示头像,名字,消息内容等的contentView和滑动才能显示出来的删除,置顶的右边菜单menuVi ...
- oracle selinux 问题
Error: cannot restore segment prot after reloc: Permission Denied http://www.oracledistilled.com/ora ...
- 技术博客HTML
<!DOCTYPE html> <html lang="en"> <head> <meta charset="U ...