[agc003e]Sequential operations on Sequence
2017-10-27 10:12
465 查看
前言
利用了经典性质的题。题目大意
有一个数字串S,初始长度为n,是1 2 3 4 …… n。有m次操作,每次操作给你一个正整数a[i],你先把S无穷重复,然后把前a[i]截取出来成为新的S。
求m次操作后,每个数字在S中出现的次数。
做法
考虑这样一个过程,solve(x,l)表示在第x次操作后的S的前l位,我们希望获取每个数在这里面的出现次数(这个函数返回一个数组)。不妨设S[i]表示第i次操作后的S每个数字出现的次数(即值是一个数组)
显然solve(x,l)=l/a[x-1]*S[x-1]+solve(x-1,l%a[x-1])。
我们发现,如果l<a[x−1],这就直接等于solve(x-1,l)。
比起一个一个这样操作,如果我们每步都找到a[y]<=l的最大的y呢?
有一个经典性质,一个数每次模不大于它的数,只会模log次。
证明显然。
这样我们只会跳log步!
于是我们一定可以把S[i]表示成log个小于i的S[j]乘上一些系数的和,再加上一个边界的前缀。
那么不妨倒推,用cnt[i]表示S[i]在答案中计算次数,就可以递推到前面的cnt[j]。
最后把那些前缀系数标记到数组上,倒扫求和即可求出答案。
不太明白的可以看代码实现。
#include<cstdio> #include<algorithm> #define fo(i,a,b) for(i=a;i<=b;i++) #define fd(i,a,b) for(i=a;i>=b;i--) using namespace std; typedef long long ll; const int maxn=100000+10,maxtot=maxn*25; ll ans[maxn],cnt[maxn],a[maxn],b[maxn],tree[maxtot],p[maxn][70][2]; int root[maxn],left[maxtot],right[maxtot],rk[maxn]; int len[maxn]; int i,j,k,l,t,n,m,tot,top,num; int newnode(int x){ tree[++tot]=tree[x]; left[tot]=left[x]; right[tot]=right[x]; return tot; } void insert(int &x,int l,int r,int a,int b){ x=newnode(x); tree[x]=b; if (l==r) return; int mid=(l+r)/2; if (a<=mid) insert(left[x],l,mid,a,b);else insert(right[x],mid+1,r,a,b); } int query(int x,int l,int r,int a,int b){ if (!x||a>b) return 0; if (l==a&&r==b) return tree[x]; int mid=(l+r)/2; if (b<=mid) return query(left[x],l,mid,a,b); else if (a>mid) return query(right[x],mid+1,r,a,b); else return max(query(left[x],l,mid,a,mid),query(right[x],mid+1,r,mid+1,b)); } void solve(int x,ll l){ int t=upper_bound(b+1,b+num+1,l)-b-1; int y=query(root[x-1],1,num,1,t); if (!y){ if (l>=n){ p[i][++top][0]=0; p[i][top][1]=l/n; l%=n; } p[i][++top][0]=l; return; } p[i][++top][0]=y; p[i][top][1]=l/a[y]; solve(y,l%a[y]); } int main(){ scanf("%d%d",&n,&m); a[0]=n; fo(i,1,m) scanf("%lld",&a[i]),b[i]=a[i]; //b[++m]=n; sort(b+1,b+m+1); num=unique(b+1,b+m+1)-b-1; b[++num]=2000000000000000000; fo(i,1,m) rk[i]=lower_bound(b+1,b+num+1,a[i])-b; fo(i,1,m){ root[i]=root[i-1]; insert(root[i],1,num,rk[i],i); } fo(i,1,m){ top=0; solve(i,a[i]); len[i]=top; } cnt[m]=1; fd(i,m,1){ fo(j,1,len[i]-1) cnt[p[i][j][0]]+=cnt[i]*p[i][j][1]; ans[p[i][len[i]][0]]+=cnt[i]; } ans +=cnt[0]; fd(i,n,1) ans[i]+=ans[i+1]; fo(i,1,n) printf("%lld\n",ans[i]); }
相关文章推荐
- [agc003e]Sequential operations on Sequence
- [二分 单调队列] Atcoder AGC003 E. Sequential operations on Sequence
- AtCoder Grand Contest 003 E - Sequential operations on Sequence 乱搞
- OpenCV_Tutorials——CORE MODULE.THE CORE FUNCTIONALITY—— Mask operations on matrices
- Operations on basic server (by Python)
- a previous program installation created pending file operations on the installation machine
- Rust: Operations with sequence
- Operations on Surface_mesh in CGAL
- opencv3学习笔记(三)——core组件之模块operations on array
- Operations on Numbers & Strings
- Android WiFi On/Off sequence diagram
- LSTM对比GRU:Empirical Evaluation of Gated Recurrent Neural Networks on Sequence Modeling
- 184.You suspect unauthorized data manipulation language (DML) operations on a particular table. You
- ORA-22804: remote operations not permitted on object tables or user-defined type columns
- 安装sql2000: 出现 A previous program installation created pending file operations on the installation machine. You must restart the computer before running setup
- Assignment | 05-week2 -Part_1-Operations on word vectors
- 从不sequential的sequence
- [转]Installing python 2.7 on centos 6.3. Follow this sequence exactly for centos machine only
- High Waits on 'Db File Sequential Read' Due to Table Lookup Following Index Access (文档 ID 875472.1)