【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的方法:项目场景:项 ...
随机推荐
- 用Python实现多站点运维监控
在小型公司里如果产品线单一的话,比如就一个app, 一般1~2个运维就够用了.如果产品过于庞大,就需要多个运维人员. 但对于多产品线的公司来说,运维人员就要必须分多个人负责,因为超过200个站点让1个 ...
- 智慧树mooc自动刷课代码
最近学习javaScript和JQuery,恰好还有一门mooc没有看.结合学习的知识和其他人的代码:撸了一个自动播放课程的代码,同时自动跳过单章的测试题. 用电脑挂着不动就完事了. 如下: var ...
- Bellman-ford 模板
#include<bits/stdc++.h> const int inf=0x3f3f3f3f; ; struct edge{ int u,v;//两个点 int w; //权值 Edg ...
- Elasticsearch 统计代码例子
aggs avg 平均数 最近15分钟的平均访问时间,upstream_time_ms是每次访问时间,单位毫秒 { "query": { "filtered": ...
- Python多重赋值
可以将变量名视对象的一个链接 >>>foo1 = foo2 = 4.3 >>>foo1 is foo2 True >>>foo1 = 4.3 &g ...
- day-19 多种优化模型下的简单神经网络tensorflow示例
如下样例基于tensorflow实现了一个简单的3层深度学习入门框架程序,程序主要有如下特性: 1. 基于著名的MNIST手写数字集样例数据:http://yann.lecun.com/exdb/m ...
- C++进阶训练——停车收费系统设计
一.简介 经过一段时间的c++基础学习,是时候做一个较为全面的.运用c++功能的较复杂的项目练练手了. 运用软件:Visual Studio (VS). 题目:c++停车收费系统设计(某本编程书进 ...
- 20130501-Twitter向全美用户开放广告平台Twitter Ads
腾讯科技讯(晁晖)北京时间5月1日消息,据国外媒体报道,Twitter今天向所有美国用户开放了广告平台Twitter Ads.自2012年3月发布以来,Twitter Ads只向受邀请用户开放.Twi ...
- [转]oracle数据库定时任务dbms_job的用法详解
这篇文章给大家详细介绍了dbms_job的用法,用于安排和管理作业队列,通过使用作业,可以使ORACLE数据库定期执行特定的任务.有需要的朋友们可以参考借鉴. 一.dbms_job涉及到的知识点 ...
- Javascript中Generator(生成器)
阅读目录 Generator的使用: yield yield* next()方法 next()方法的参数 throw方法() return()方法: Generator中的this和他的原型 实际使用 ...