hdu5288 vector用法+ ……(多校1.1)
来源:互联网 发布:ubuntu 支持中文 编辑:程序博客网 时间:2024/06/05 00:49
题目大意:给定一个序列含有n个数,定义f(l,r) = l ~r序列中没有因子的数的个数 ,求n个数的序列中所有的连续子序列的f和。对1000000007取模
思路:定义数组l , r .l[i] , r[i] 分别表示第i个元素左边最近因子的位置和右边最近的因子的位置。则第i个数贡献的f值为(i - l[i]) * (r[i] - i )。
在求l 和r的过程中,肯定不能每个因子都去遍历着找,必然会超时。首先,一个数a的因子必然在sqrt(a)内能找到,所以只需要枚举从sqrt(a)到1所有的因子,找到最近的一个l和r
即可。然后就是如何尽快的找到因子所在的位置,刚才说了,肯定不能去遍历,不然必然超时,如何用元素来确定他的下标?就想到了STL里面的vector,可以开10000个vector,
就定义为vector<int > v[10000],然后输入a[i]时。只需要v[a[i]].push_back(i)即可,然后查找的时候遍历即可,其实和hash思想差不多。
另外强调一点,x是y的因子,则y/x也是y的因子,y/x比一定小于sqrt(y)!!
#include <iostream>#include <cstdio>#include <string>#include <cstring>#include <fstream>#include <algorithm>#include <cmath>#include <queue>#include <stack>#include <vector>#include <map>#include <set>#include <iomanip>using namespace std;#define MAXN 100005#define MOD 1000000007int a[MAXN] , l[MAXN] , r[MAXN];int load[10005];vector<int> v[10005];vector<int>::iterator it;int n;void slove(int pos){ int num = (int)sqrt(a[pos]); if(num * num != a[pos]) num ++; int maxl = 0; int minr = n + 1; for(int i = num ; i > 0 ; i --) { if(a[pos] % i != 0) continue; //若不是因子,直接下一个 int res = a[pos] / i; //是因子 , 则要找到他的另一个因子,一起判断 for(int j = 0; j < v[i].size() ; j ++ ) { if(v[i][j] < pos) maxl = max (maxl , v[i][j]); if(v[i][j] > pos) minr = min (minr , v[i][j]); } for(int j = 0; j < v[res].size() ; j ++ ) { if(v[res][j] < pos) maxl = max (maxl , v[res][j]); if(v[res][j] > pos) minr = min (minr , v[res][j]); } } l[pos] = maxl; r[pos] = minr; return ;}int main(){ while(scanf("%d" , &n) != EOF) { memset(l , 0 , sizeof(l)); memset(r , 0 , sizeof(r)); for(int i = 1 ; i <= 10000 ; i ++ ) v[i].clear(); for(int i = 1 ; i <= n ; i ++ ) { scanf("%d" , &a[i]); v[a[i]].push_back(i); //记录每个数字的位置 } for(int i = 1 ; i <= n ; i ++ ) { slove(i); //找到l,r } int sum = 0; for(int i = 1 ; i <= n ; i ++ ) { sum = (sum + (i - l[i])*(r[i] - i) % MOD ) % MOD; } cout << sum << endl; } return 0;}
0 0
- hdu5288 vector用法+ ……(多校1.1)
- hdu5288 多校
- hdu5288 多校
- hdu5288
- hdu5288
- HDU5288
- hdu5288(2015多校1)OO’s Sequence
- vector用法 (一)
- Vector(ACM)用法
- HDU5288 OO’s Sequence(暴力枚举)
- HDU5288:OO’s Sequence(思维)
- vector用法 (二) 迭代器
- C++vector用法(转)
- c++ vector用法(转)
- vector基本用法(转载)
- vector<vector<int>> 用法
- C++里的vector用法,比数组方便很…
- Vector用法
- java webservice简单实现
- Remove Duplicates from Sorted Array
- 20150802-BufferedReader和BufferedWriter
- c#委托
- HashSet
- hdu5288 vector用法+ ……(多校1.1)
- 剑指Offer面试题20(Java版):顺时针打印矩阵
- C语言 -- 定时关机程序
- List
- BufferedReader, BufferedWriter
- HNU Judging Troubles (字典树)
- 69. Sqrt(x)
- 入门【windows SDK】级教程
- Read