【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的方法:项目场景:项 ...
随机推荐
- sql 命令使用简单记录
半个月前就想记下用过的SQL命令的!!! 主题: 按时间查询: https://blog.csdn.net/hejpyes/article/details/41863349 左关联: se ...
- AWS探索及创建一个aws EC2实例
一.AWS登陆 1.百度搜索aws,或者浏览器输入:http://aws.amazon.com 2.输入账户及密码登陆(注册流程按照提示走即可) 二.创建EC2实例(相当于阿里云的ecs) 1.找到E ...
- Linux 安装Zookeeper<准备>(使用Mac远程访问)
阅读本文需要安装JDK 一 Zookeeper简介 zookeeper是用java语言编写的一款为分布式应用所设计的协调服务 zookeeper是apacahe hadoop的子项目 使用zookee ...
- WebGL树形结构的模型渲染流程
今天和大家分享的是webgl渲染树形结构的流程.用过threejs,babylonjs的同学都知道,一个大模型都是由n个子模型拼装而成的,那么如何依次渲染子模型,以及渲染每个子模型在原生webgl中的 ...
- 袋鼠云研发手记 | 数栈·开源:Github上400+Star的硬核分布式同步工具FlinkX
作为一家创新驱动的科技公司,袋鼠云每年研发投入达数千万,公司80%员工都是技术人员,袋鼠云产品家族包括企业级一站式数据中台PaaS数栈.交互式数据可视化大屏开发平台Easy[V]等产品也在迅速迭代.在 ...
- 从零开始的Python学习Episode 11——装饰器
装饰器 装饰器是用来处理其他函数的函数,主要作用是在不修改原有函数的情况下添加新的功能,装饰器的返回值也是一个函数对象. 简单的装饰器 import time def show_time(f): de ...
- 1.hive介绍及安装配置
1.Hive介绍 数据库OLTP 在线事务处理 数据仓库OLAP 在线分析处理 延迟高 类sql方式(HQL) 使用sql方式,用来读写,管理位于分布式存储系统上的大型数据集的数据仓库技术 hive是 ...
- 详解Python中的下划线
本文将讨论Python中下划线(_)字符的使用方法.我们将会看到,正如Python中的很多事情,下划线的不同用法大多数(并非所有)只是常用惯例而已. 单下划线(_) 通常情况下,会在以下3种场景中使用 ...
- Scrum立会报告+燃尽图(06)选题
此作业要求参见:[https://edu.cnblogs.com/campus/nenu/2018fall/homework/2195] 一.小组介绍 组长:王一可 组员:范靖旋,王硕,赵佳璐,范洪达 ...
- Android开发第二阶段(3)
今天:对闹钟代码的按钮事件进行了添加和修改.对监听器的相关应用也有了进一步的了解和深入. 明天:对主界面的代码的优化比如对按钮位置的调节等细节处理.