CSU 1810 Reverse (组合计数)
来源:互联网 发布:阿根廷04男篮名单 数据 编辑:程序博客网 时间:2024/06/06 15:51
1810: Reverse
Time Limit: 5 Sec Memory Limit: 128 Mb Submitted: 189 Solved: 90
Description
Input
Output
Sample Input
2123012100123456789
Sample Output
45369733424314
Hint
Source
湖南省第十二届大学生计算机程序设计竞赛计数的题目总是受欢迎。
这题题意是可以每次反转一个区间,得到一个数字,然后问你把所有这样不重复的反转之后的数字加起来,结果是多少。
这种题目通常都是计算贡献,但是计算贡献也有好几种方式,这里就是计算每一个位置对最后结果的贡献。注意到,交换两个区间,实际上可能对某些位置不产生影响,所以说我们分成两种情况,一是这个位置还是原本的数字,二是这个位置是别的数字。当这个位置是原本的数字的时候,相当于只需要计算有多少个这样不影响该位置的区间。这个又可以分为两种情况,意识反转区间根本不包含这个位置,显然有i*(i-1)/2+(n-i)*(n-i+1)/2种;另一种是区间包含这个位置,但是这里是对称轴,显然有min(i,n-i+1)中。
然后就计算这个位置不是原本的数字的情况。我们以左边为例子说明,假如说第i个位置反转之后是原本的第j个数字,可以看出这个的条件就是对称轴固定在i与j之间,那么满足条件的区间就有min(j,n-i+1)个,这个自己画画就能理解。知道了这个我们就可以再仔细看看这个怎么计算,由于有min(j,n-i+1),所以还是一样分两种情况,当j大的时候这个贡献就是(n-i+1)*a[j],而当j小的时候贡献就是j*a[j]。可以看到,对于一个固定的i,有一部分的贡献是对应j*a[j]的和,一部分是(n-i+1)*a[j],1<=j<=i。那么当i<=n-i+1的时候,贡献直接就是j*a[j]的前缀和。反之,如果i>n-i+1,那就要分成两部分分别相加计算。
计算完每一位的贡献之后,先把当前ans乘以10,然后在把当前位置的值加上去。具体见代码:
#include<algorithm>#include<iostream>#include<cstring>#include<cstdio>#include<vector>#include<cmath>#define mod 1000000007#define LL long long#define N 100010using namespace std;LL a[N],sl[N],sr[N],SL[N],SR[N];char ch[N]; int n;int main(){ while(~scanf("%d%s",&n,ch)) { sr[n+1]=SR[n+1]=0; for(int i=0;i<n;i++) a[i+1]=ch[i]-48; for(int i=1;i<=n;i++) { sl[i]=(sl[i-1]+a[i])%mod; SL[i]=(SL[i-1]+(LL)a[i]*i)%mod; sr[n-i+1]=(sr[n-i+2]+a[n-i+1])%mod; SR[n-i+1]=(SR[n-i+2]+a[n-i+1]*i)%mod; } LL ans=0,res; for(int i=1;i<=n;i++) { res=a[i]*((LL)i*(i-1)/2+(LL)(n-i)*(n-i+1)/2)%mod; res+=(LL)a[i]*min(i,n-i+1)%mod; if (i-1>=n-i+1) { res+=SL[n-i+1]; res+=(LL)(sl[i-1]-sl[n-i+1])*(n-i+1)%mod; } else res+=SL[i-1]; if (n-i>=i) { res+=SR[n-i+1]; res+=(LL)(sr[i+1]-sr[n-i+1])*i%mod; } else res+=SR[i+1]; ans=(ans*10%mod+res)%mod; } printf("%lld\n",ans); } return 0;}
- CSU 1810 Reverse (组合计数)
- CSU 1810 Reverse
- CSU 1810 Reverse(贡献)
- CSU 1810 Reverse(贡献)
- CSU 1810: Reverse
- CSU 1810 Reverse
- CSU 1810: Reverse
- CSU 1784 Internet of Lights and Switches(状态压缩+组合计数)
- Combinations(组合计数)
- csu oj 1008 Horcrux(计数)
- CSU 1563: Lexicography (数学计数问题)
- POJ 3761 (组合计数)
- Uva 10247 (组合计数)
- 组合计数总结(转)
- 数字组合(背包计数)
- csu 1567: Reverse Rot
- CSU-1567-Reverse Rot
- CSU 1567Reverse Rot
- 【Machine Learning】笔记:Semi-supervised learning
- Unity2d组件 Sprite Renderer
- android Binder与AIDL
- 理解和使用systrace
- 高精度加法
- CSU 1810 Reverse (组合计数)
- 二级MySQL数据库程序设计考试大纲(2015年版)
- PAT1006. 换个格式输出整数 (15)
- LVS(一)
- maven基础之新建项目
- BAT脚本编写教程
- 【unity学习笔记】unity实现钩子功能
- jvm_方法区溢出(PermGen Space)
- caioj1032:递归2(组合)