题目地址:http://acm.hdu.edu.cn/showproblem.php?pid=5869
题目:
给定序列和要查询的区间[L,R],求[L,R]内有多少个不同的区间gcd
解题思路:
(1)遍历序列,预处理出以a[i]为结尾的区间的gcd并记录,注意,有多个以a[i]为结尾的区间gcd相同,取左边界最大的那个,这样在用线段树求不同区间gcd的数目时,就避免了-1和+1的更新,节省时间和空间。为了取左边界最大的那个,可以倒序处理,即依次求[i,i] [i-1,i] [i-2,i]...[1,i]的区间gcd,如果当前求的gcd和上次求的gcd相同,则不更新这个gcd对应的左边界。
尝试自己写代码遇到的问题:不能用map<int,int> gd[maxn],因为map自动按照key值从小到大排序,影响结果,可以用pair和vector。此外,也不能用map中的key来存【x,i】的左边界x,如果这样的话在预处理时实践复杂度就达到了(n+1)*n/2, 会超时。
正确的处理方法:
vector<pair<int, int> > gd[maxn];//gd[i]中记录的是以a[i]为末尾的所有的gcd,<key,value>,表示【value,i】的区间gcd为key
void getIntervalGcd()
{
for(int i = 1; i