Portal -->agc003E

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的更多相关文章

  1. 【AGC003 E】Sequential operations on Sequence

    Description 你有一个长度为 \(n\) 的序列,第 \(i\) 项为 \(i\). 有 \(m\) 次操作,每次操作给定一个 \(x\),你需要将序列无限循环后截取前 \(x\) 项,作为 ...

  2. 【BZOJ1345】[Baltic2007]序列问题Sequence 贪心+单调栈

    [BZOJ1345][Baltic2007]序列问题Sequence Description 对于一个给定的序列a1, …, an,我们对它进行一个操作reduce(i),该操作将数列中的元素ai和a ...

  3. 【SPOJ】1182 Sorted bit sequence

    [算法]数位DP [题解]动态规划 写了预处理函数却忘了调用是一种怎样的体验? #include<cstdio> #include<cstring> #include<a ...

  4. 【做题】agc003E - Sequential operations on Sequence——经典结论

    题意:有一个序列,初始是从\(1\)到\(n\)的\(n\)个数.有\(q\)次操作,每次操作给出\(q_i\),把当前的序列重复无数遍,然后截取最前面的\(q_i\)个元素作为新序列.要求输出完成所 ...

  5. agc003E Sequential operations on Sequence

    题意: 有一个数字串S,初始长度为n,是1 2 3 4 …… n. 有m次操作,每次操作给你一个正整数a[i],你先把S无穷重复,然后把前a[i]截取出来成为新的S. 求m次操作后,每个数字在S中出现 ...

  6. 线段树【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 ...

  7. 题解【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 ...

  8. 【转】Oracle数据库中Sequence的用法

    在Oracle数据库中,sequence等同于序列号,每次取的时候sequence会自动增加,一般会作用于需要按序列号排序的地方. 1.Create Sequence (注释:你需要有CREATE S ...

  9. 【转】MySQL中增加sequence管理功能(模拟创建sequence)

    1.oracel可以直接支持sequence,但是mysql不支持sequence,因此我们要通过模拟sequence的方法在mysql中创建sequence.模拟sequence的方法:项目场景:项 ...

随机推荐

  1. 用MYSQLworkbench导出数据excel

    步骤: 1.先从数据库中将表导出,右键需要导出的表格——>Table Data Export Wizard 2.点击Next,选择你需要把数据存放的文件路径.导出的数据格式(表格的话就默认选择C ...

  2. Linux 安装Redis<集群版>(使用Mac远程访问)

    阅读本文需要先阅读安装Redis<准备> 一 架构细节 所有的redis节点彼此互联(PING-PONG机制) 内部使用二进制协议优化传输速度和带宽 节点的fail是通过集群中超过半数的节 ...

  3. 【TCP_协议_socket接口】-jmeter

    1.ip 2.端口号 3.传入参数 4.告诉软件返回  最后以为是什么,不然就会报错 或者无限制的等待  查ascll 码表 启动接口的方法

  4. MongoDB Chapter1:Introduction

    你是在防火墙后面吗? 为了继续本课程,您必须能够将计算机的传出请求发送到我们在MongoDB Atlas中设置的数据库服务器.这些服务器在Amazon AWS中的端口27017上运行. 请单击http ...

  5. 【Pthon入门学习】多级菜单小例子

    menu_list = { '北京':{ '昌平':{ '回龙观':{ '和谐家园':{}, '矩阵小区':{}, '北店家园':{} }, '沙河':{ '北街家园1区':{}, '北街家园2区': ...

  6. [转]oracle数据库定时任务dbms_job的用法详解

    这篇文章给大家详细介绍了dbms_job的用法,用于安排和管理作业队列,通过使用作业,可以使ORACLE数据库定期执行特定的任务.有需要的朋友们可以参考借鉴.   一.dbms_job涉及到的知识点 ...

  7. javascript中的取反再取反~~

    操作符~, 是按位取反的意思,表面上~~(取反再取反)没有意义,实际上在JS中可以将浮点数变成整数. <html> <script> var myArray = new Arr ...

  8. 【转载】windows安装python2.7后的注册表问题

    原文出自:https://www.cnblogs.com/tlz888/p/6879227.html [提要]win平台上,python2.7官网的安装包在安装后不会添加环境变量且不会把安装信息写入注 ...

  9. Beta阶段中间产物

    空天猎功能说明书:https://git.coding.net/liusx0303/Plane.git 空天猎代码控制:https://coding.net/u/MR__Chen/p/SkyHunte ...

  10. android入门 — 多线程(一)

    android中的一些耗时操作,例如网络请求,如果不能及时响应,就会导致主线程被阻塞,出现ANR,非常影响用户体验,所以一些耗时的操作,我们会想办法放在子线程中去完成. android的UI操作并不是 ...