zoukankan      html  css  js  c++  java
  • 数据结构水题大赛官方题解#2 XXX的脑白金

    数据结构水题大赛 T2

    XXX的脑白金

    题面

    洛谷链接

    题解

    本题就是要求查询一个区间最大值除以区间gcd的商. 有(20')的暴力得分, 可以用线段树得(60'), 正解是st表(是不是感觉有点面熟? 没错, t1也是这样)

    20'暴力

    这个不用说了, 直接几层循环套娃就能过

    60'线段树

    构造两棵线段树, 分别维护区间gcd, 区间最大值, 每次查询两个值, 输出 (区间最大值 / 区间gcd)

    单次查询时间复杂度 (O(logn))

    100'st表

    因为一个数重复计算不会影响区间gcd, 所以区间gcd可以用st表维护, (O(1))查询

    区间最值可以用st表维护, 所以也可以(O(1))查询

    AC代码

    #include <algorithm>
    #include <cmath>
    #include <cstdio>
    #include <cstdlib>
    #include <cstring>
    #include <ctime>
    #include <iostream>
    #include <map>
    #include <queue>
    #include <vector>
    using namespace std;
    int m, n, st[15][10005][2], ans = 0, two[10005], A, B;
    bool flg;
    char ch;
    string s;
    inline int IN() {
      char ich = getchar();
      int intmp = 0, insign = 1;
      while (((ich < '0') || (ich > '9')) && ((ich != '-'))) {
        ich = getchar();
      }
      if (ich == '-') {
        insign = -1;
        ich = getchar();
      }
      while ((ich <= '9') && (ich >= '0')) {
        intmp *= 10;
        intmp += ich - '0';
        ich = getchar();
      }
      return intmp * insign;
    }
    inline int G (const int x, const int y) {
    	if (y) {
    		return G (y, x%y);
    	}
    	else{
    		return x;
    	}
    }
    inline void ask () {
    	A = IN();
    	B = IN();
    	int tmp(two[B - A + 1]), tmp2(1 << tmp);
    	printf("%d
    ", max(st[tmp][A][1], st[tmp][B - tmp2 + 1][1]) / G(st[tmp][A][0], st[tmp][B - tmp2 + 1][0]));
    }
    int main() {
        n = IN();
        for (register int i(1); i <= n; ++i) {
        	st[0][i][2] = st[0][i][1] = st[0][i][0] = IN();
        }
        int cnt(0);
        for (register int i(1); i <= n; ++i) {
        	if(1 << (cnt + 1) <= i) {
        		two[i] = ++cnt;
    		}
    		else {
    			two[i] = cnt;
    		}
    	}
        for (register int i(1), ii(0); i <= n; i <<= 1, ++ii) {
        	int j(0);
    		while((++j) + (i << 1) <= n + 1) {
    			st[ii + 1][j][0] = G(st[ii][j][0], st[ii][j + i][0]);
    			st[ii + 1][j][1] = max(st[ii][j][1], st[ii][j + i][1]);
    		}
    	}
    	m = IN();
    	for(register int i(1); i <= m; ++i) {
    		ask();
    	}
    	return 0;
    }
    
  • 相关阅读:
    day02_1spring3
    day01_2spring3
    动态代理的介绍
    day04_1hibernate
    day03_2hibernate
    Oracle11gR2安装完成后不手动配置监听的使用方法
    css的样式和选择符的优先权
    调用css时,link和@import url的区别
    jquery 获取和修改img标签的src属性
    正则表达式实现6-10位密码由数字和字母混合组成
  • 原文地址:https://www.cnblogs.com/Wild-Donkey/p/13329847.html
Copyright © 2011-2022 走看看