hdu 5869 Different GCD Subarray Query 预处理 + 离线
来源:互联网 发布:linux 强行退出vim 编辑:程序博客网 时间:2024/05/21 01:45
// hdu 5869 Different GCD Subarray Query 预处理 + 离线//// 题目链接://// http://acm.split.hdu.edu.cn/showproblem.php?pid=5869//// 题目大意://// 给定数组,求[L,R]段中所有子段的不同gcd的种类//// 解题思路://// 根据XJ的题解,固定左端点的不同GCD的值,这个值是不超过logA// 这样,我们可以预处理出对于当前a{i},求出[1,i-1]的gcd值,然后// 将查询按照右端点排个序,固定右端点,用树状数组求出[L,i]的gcd// 的个数。当然,我们必须每次加入gcd到最右边界,因为只有最右边界// 是最小的区间,在最右边界之前的区间都可以去到这个gcd的值。所以// 用个vis数组存储边界//// 感悟://// 这类题以前没有接触过,所以,当看到XJ的题解的时候,整个人处// 于懵X状态,研究了差不多一个小时吧(ok,说实话是取得min),看着// 代码还是挺亲切的,预处理还挺好理解的,之后的按右边界,可以放入// vector中,省去排序的时间,只是因为各种手残,GG一下午。继续努力// ^_^#include <cstdio>#include <iostream>#include <cstring>#include <vector>#include <stack>#include <set>#include <queue>#include <algorithm>using namespace std;typedef long long ll;typedef pair<int,int> pii;const int MAXN = 1e5 + 8;int a[MAXN];int ans[MAXN];vector<pii> gc[MAXN];vector<pii> query[MAXN];int vis[MAXN * 10];int n,q;struct SegmentTree{#define lowbit(x) (x & (-x)) int sum[MAXN]; void init(){ memset(sum,0,sizeof(sum)); } void update(int x,int v){ while(x <= n){ sum[x] += v; x += lowbit(x); } } int getSum(int x){ int ans = 0; while(x){ ans += sum[x]; x -= lowbit(x); } return ans; }}it;void init(){ for (int i = 0;i <= n;i ++){ gc[i].clear(); query[i].clear(); } memset(vis,0,sizeof(vis)); it.init();}void input(){ for (int i = 1;i <= n;i ++) scanf("%d",a + i); for (int i = 1;i <= n;i ++){ int x = a[i]; int y = i; for (int j = 0; j < gc[i - 1].size();j ++){ int res = __gcd(gc[i - 1][j].first,x); if (x != res){ gc[i].push_back(make_pair(x,y)); x = res; y = gc[i - 1][j].second; } } gc[i].push_back(make_pair(x,y)); } for (int i = 1;i <= q;i ++){ int l,r; scanf("%d%d",&l,&r); query[r].push_back(make_pair(l,i)); } for (int i = 1;i <= n;i ++){ for (int j = 0;j < gc[i].size();j ++){ int res = gc[i][j].first; int ind = gc[i][j].second; if (vis[res]) it.update(vis[res],-1); vis[res] = ind; it.update(ind,1); } for (int j = 0;j < query[i].size();j ++){ int l = query[i][j].first; int ind = query[i][j].second; ans[ind] = it.getSum(i) - it.getSum(l - 1); } } for (int i = 1;i <= q;i++){ printf("%d\n",ans[i]); }}int main(){ while(scanf("%d%d",&n,&q)!=EOF){ init(); input(); } return 0;}
0 0
- hdu 5869 Different GCD Subarray Query 预处理 + 离线
- hdu-5869 Different GCD Subarray Query gcd预处理 + 树状数组 + 离线
- HDU 5869 Different GCD Subarray Query [区间gcd预处理+离线]【数据结构】
- [区间GCD预处理 树状数组 离线] HDU 5869 Different GCD Subarray Query
- HDU 5869 Different GCD Subarray Query(离线+gcd)
- HDU 5869 Different GCD Subarray Query 离线 树状数组
- hdu 5869 Different GCD Subarray Query 离线+树状数组
- HDU 5869 Different GCD Subarray Query(离线处理+树状数组)
- HDU 5869 Different GCD Subarray Query (离线处理 树状数组)
- HDU 5869 Different GCD Subarray Query
- hdu 5869 Different GCD Subarray Query
- HDU 5869 Different GCD Subarray Query
- HDU 5869 Different GCD Subarray Query (数学gcd+树状数组离线查询)
- [HDU 5869] Different GCD Subarray Query (线段树GCD+离线算法) (好题)
- Different GCD Subarray Query HDU
- Hdu-5869 Different GCD Subarray Query(区间不同值离线算法)
- Different GCD Subarray Query (离线的处理)
- hdu 5869 Different GCD Subarray Query(gcd+树状数组)
- 微型电脑-树莓派
- (转)C语言预处理命令大全
- 关于TI cc2640
- BFS-小学期考核
- 《机器学习实战》学习(三)——决策树实例
- hdu 5869 Different GCD Subarray Query 预处理 + 离线
- 逆波兰表达式求值
- Java 设计模式 之 工厂模式
- VS下使用freopen重定向输入流至文件同时使用system("pause")暂停
- 友录联系人板块
- 质数与完全平方数的判断
- 第二周项目3(2)-汉诺塔
- character sets and collations in mysql
- POJ 1830 开关问题