CSU 1810 Reverse
湖南省第十二届大学生计算机程序设计竞赛$H$题
规律,递推。
这种问题一看就有规律。可以按位统计对答案的贡献。即第$1$位对答案作出了多少贡献,第$2$位对答案作出了多少贡献.....累加和就是答案。
先写一个暴力的程序来找找规律:
#pragma comment(linker, "/STACK:1024000000,1024000000")
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<vector>
#include<map>
#include<set>
#include<queue>
#include<stack>
#include<iostream>
using namespace std;
typedef long long LL;
const double pi=acos(-1.0),eps=1e-;
void File()
{
freopen("D:\\in.txt","r",stdin);
freopen("D:\\out.txt","w",stdout);
}
template <class T>
inline void read(T &x)
{
char c = getchar();
x = ;
while(!isdigit(c)) c = getchar();
while(isdigit(c))
{
x = x * + c - '';
c = getchar();
}
} const int maxn=;
struct X
{
int p;
}s[maxn];
int n;
int f[maxn][maxn]; int main()
{
while(~scanf("%d",&n))
{
memset(f,,sizeof f);
for(int i=;i<=n;i++) s[i].p=i; for(int i=;i<=n;i++)
{
for(int j=i;j<=n;j++)
{
for(int k=i;k<=(i+j)/;k++) swap(s[k],s[j-(k-i)]); for(int k=;k<=n;k++) f[s[k].p][k]++; for(int k=i;k<=(i+j)/;k++) swap(s[k],s[j-(k-i)]);
}
} for(int i=;i<=n;i++)
{
int sum=;
for(int j=;j<=n;j++)
{
// sum=sum+(int)pow(10.0,j-1)*f[i][j];
printf("%3d ",f[i][j]);
}
printf("\n");
// printf("%d ",sum);
}
printf("\n"); }
return ;
}
上面的代码中,$f[i][j]$表示$i$这一位,所有交换中,在$j$位出现了几次;答案就是$\sum\limits_{i = 1}^n {\left( {s[i]×\left( {\sum\limits_{j = 1}^n {f[i][j]×{{10}^{j - 1}}} } \right)} \right)} $。
输出来看一下$n=10$和$n=11$时候的情况,看看$f[i][j]$有没有什么规律:

通过观察可以发现:
$[1].$每一行的和都是一样的,$n=x$时,每一行的和$cnt[x]$都是一样的,并且$cnt[x]=x+cnt[x-1]$。
$[2].$第$i$行的贡献${\sum\limits_{j = 1}^n {f[i][j]×{{10}^{j - 1}}} }$可以由第$i-1$行的贡献${\sum\limits_{j = 1}^n {f[i-1][j]×{{10}^{j - 1}}} }$递推而来。
也就是说,我们可以$O(n)$效率得到每一位的贡献,然后乘上输入的那个权值就是答案了。
#pragma comment(linker, "/STACK:1024000000,1024000000")
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<vector>
#include<map>
#include<set>
#include<queue>
#include<stack>
#include<iostream>
using namespace std;
typedef long long LL;
const double pi = acos(-1.0), eps = 1e-;
void File()
{
freopen("D:\\in.txt", "r", stdin);
freopen("D:\\out.txt", "w", stdout);
}
template <class T>
inline void read(T &x)
{
char c = getchar(); x = ; while (!isdigit(c)) c = getchar();
while (isdigit(c)) { x = x * + c - ''; c = getchar(); }
} const LL mod = 1e9 + ;
const int maxn = ;
LL a[maxn], cnt[maxn], POW[maxn], sPOW[maxn], num[maxn];
char s[maxn];
int n; int main()
{
cnt[] = ;
for (int i = ; i <= ; i++) cnt[i] = (cnt[i - ] + i) % mod;
POW[] = ; sPOW[] = ;
for (int i = ; i <= ; i++)
{
POW[i] = (LL) * POW[i - ] % mod;
sPOW[i] = (sPOW[i - ] + POW[i]) % mod;
} while (~scanf("%d%s", &n, s))
{
memset(num, , sizeof num);
memset(a, , sizeof a); num[] = (cnt[n] - (n - ) + mod) % mod;
a[] = (num[]*POW[] % mod + (sPOW[n - ] - sPOW[] + mod) % mod) % mod; int L = , R = n - ;
for (int i = ; i < n / ; i++)
{
L++, R--; num[i] = (num[i - ] - (R - L + ) + mod) % mod;
a[i] = (a[i - ] + sPOW[R] - sPOW[L - ] + mod) % mod;
a[i] = (a[i] + ((num[i] - i + mod) % mod)*POW[i] % mod) % mod;
a[i] = (a[i] - (((num[i - ] - i + mod) % mod)*POW[i - ] % mod) + mod) % mod;
} num[n - ] = num[];
a[n - ] = (num[n - ] * POW[n - ] % mod + sPOW[n - ]) % mod; L = , R = n - ; LL d = ;
for (int i = n - ; i >= (n ) / ; i--)
{
L++, R--; num[i]= (num[i + ] - (R - L + ) + mod) % mod;
a[i]= (a[i + ] + sPOW[R] - sPOW[L - ] + mod) % mod;
a[i] = (a[i] + ((num[i] - d + mod) % mod)*POW[i] % mod) % mod;
a[i] = (a[i] - (((num[i + ] - d + mod) % mod)*POW[i + ] % mod) + mod) % mod;
d++;
} LL ans = ;
for (int i = ; s[i]; i++) ans = (ans + (LL)(s[i] - '')*a[n-i-] % mod) % mod;
cout << ans << endl;
}
return ;
}
CSU 1810 Reverse的更多相关文章
- 【数学】CSU 1810 Reverse (2016湖南省第十二届大学生计算机程序设计竞赛)
题目链接: http://acm.csu.edu.cn/OnlineJudge/problem.php?id=1810 题目大意: 一个长度为N的十进制数,R(i,j)表示将第i位到第j位翻转过来后的 ...
- LeetCode 7. Reverse Integer
Reverse digits of an integer. Example1: x = 123, return 321 Example2: x = -123, return -321 Have you ...
- js sort() reverse()
数组中存在的两个方法:sort()和reverse() 直接用sort(),如下: ,,,,,,,,,,,]; console.log(array.sort());ps:[0, 1, 2, 2, 29 ...
- [LeetCode] Reverse Vowels of a String 翻转字符串中的元音字母
Write a function that takes a string as input and reverse only the vowels of a string. Example 1:Giv ...
- [LeetCode] Reverse String 翻转字符串
Write a function that takes a string as input and returns the string reversed. Example: Given s = &q ...
- [LeetCode] Reverse Linked List 倒置链表
Reverse a singly linked list. click to show more hints. Hint: A linked list can be reversed either i ...
- [LeetCode] Reverse Bits 翻转位
Reverse bits of a given 32 bits unsigned integer. For example, given input 43261596 (represented in ...
- [LeetCode] Reverse Words in a String II 翻转字符串中的单词之二
Given an input string, reverse the string word by word. A word is defined as a sequence of non-space ...
- [LeetCode] Reverse Words in a String 翻转字符串中的单词
Given an input string, reverse the string word by word. For example, Given s = "the sky is blue ...
随机推荐
- Bundles
Bundles 接着在Global.asax文件的Application_Start方法中调用BundleConfig.RegisterBundles方法: protected void Applic ...
- 【译】TensorFlow Python Docs 之 overview
Overview 综述 TensorFlow has APIs available in several languages both for constructing and executing a ...
- js的onclick和jquery的bind事件执行先后顺序
近期在项目中为每一个ajax触发按钮写正在加载的效果,用的是bootstarp 代码如下 $(function(){ $('.btn').bind('click',function(e){ var $ ...
- ToList<>()所带来的性能影响
ToList<>()所带来的性能影响 前几天优化师弟写的代码,有一个地方给我留下很深刻的印象,就是我发现他总是将PLINQ的结果ToList<>(),然后再返回给主程序,对于 ...
- Windows下的环境搭建Erlang
Windows下的环境搭建 Erlang 一.安装编译器 在http://www.erlang.org/download.html下载R16B01 Windows Binary File并安装. 二. ...
- setprecision、fixed、showpoint的用法总结(经典!!超经典!!)
首先要加头文件:iomanip 一:setprecision 作用:控制输出流显示浮点数的数字个数,setprecision(n)就是输出的n个数,会有四舍五入. 比如:double s=20.784 ...
- Android——另外一种增删查改的方式(ContentProvider常用)
以下介绍另外一种增删查改的方式 package com.njupt.sqllist; import java.util.ArrayList; import java.util.List; import ...
- [APUE]进程控制(中)
一.wait和waitpid函数 当一个进程正常或异常终止时会向父进程发送SIGCHLD信号.对于这种信号系统默认会忽略.调用wait/waidpid的进程可能会: 阻塞(如果其子进程都还在运行); ...
- CentOS 7下安装X Window
1.网上其他人都这么说: yum check-update yum groupinstall "X Window System" ... 但是运行yum groupinstall ...
- 近期unity ios接入的事情
1, 在接入苹果内支付的时候,遇到一个很严重的问题,使用的公司的moni2来测试的,但是在测试的过程中发现每次调用oc的内支付代码后,总会先回调一个支付成功,然后弹出输入密码框,当点击取消后,再一次 ...