hdu6098[RMQ+筛法] 2017多校6

/*hdu6098[RMQ+筛法] 2017多校6*/
#include <bits/stdc++.h>
using namespace std;
int T, n, st[100005][20], len[100005], a[100005];
void st_init() {
    len[0] = -1;
    for (int i = 1; i <= n; i++) {
        st[i][0] = a[i];
        len[i] = (i & (i - 1)) == 0 ? len[i - 1] + 1 : len[i - 1];
    }
    for (int j = 1; j <= len[n]; j++) {
        for (int i = 1; i + (1 << j) - 1 <= n; i++) {
            st[i][j] = max(st[i][j - 1], st[i + (1 << (j - 1))][j - 1]);
        }
    }
}
int query(int l, int r) {
    int k = len[r - l + 1];
    return max(st[l][k], st[r - (1 << k) + 1][k]);
}
int main() {
    scanf("%d", &T);
    while (T--) {
        scanf("%d", &n);
        for (int i = 1; i <= n; i++) {
            scanf("%d", &a[i]);
        }
        st_init();
        for (int i = 2; i <= n; i++) {
            int ans = 0;
            for (int j = 0; j < n; j += i) {
                //cout<<"["<<j+1<<", "<<min(n, j + i - 1)<<"]\n";
                ans = max(query(j + 1, min(n, j + i - 1)), ans);
            }
            if(i>2) printf(" ");
            printf("%d", ans);
        }
        puts("");
    }
    return 0;
}
时间: 2024-07-31 21:31:43

hdu6098[RMQ+筛法] 2017多校6的相关文章

hdu6069[素数筛法] 2017多校3

/*hdu6069[素数筛法] 2017多校3*/ #include <bits/stdc++.h> using namespace std; typedef long long LL; LL l, r, k; const LL MOD = 998244353LL; int T, n, prime[1100000], primesize; bool isprime[11000000]; void getlist(int listsize) { memset(isprime, 1, sizeof

hdu6035[dfs+思维] 2017多校1

/*hdu6035[dfs+思维] 2017多校1*/ //合并色块, 妙啊妙啊 #include<bits/stdc++.h> using namespace std; const double eps=1e-8; const int inf=0x3f3f3f3f; typedef long long LL; vector<int>G[200005]; LL sum[200005]; int c[200005],son[200005],mark[200005]; int n,u,

hdu6034[模拟] 2017多校1

/*hdu6034[模拟] 2017多校1*/ //暴力模拟26个26进制数即可, 要注意进位 #include<bits/stdc++.h> using namespace std; typedef long long LL; const double eps=1e-8; const int inf=0x3f3f3f3f; struct node{ char num[100005]; int ch,high; }bits[30]; const int mod=1000000007; int

hdu6078[优化递推过程] 2017多校4

/*hdu6078[优化递推过程] 2017多校4*/ #include <bits/stdc++.h> using namespace std; typedef long long LL; const LL MOD = 998244353LL; int T, m, n, a[2005], b[2005]; LL sum[2005][3], dp[2005][3]; void solve() { LL ans = 0; for (int i = 1; i <= n; i++) { LL

hdu6074[并查集+LCA+思维] 2017多校4

看了标答感觉思路清晰了许多,用并查集来维护全联通块的点数和边权和. 用另一个up[]数组(也是并查集)来保证每条边不会被重复附权值,这样我们只要将询问按权值从小到大排序,一定能的到最小的边权和与联通块中的点数. 下面是过程分析.过程中一共运用了两个并查集. [数据]110 31 21 32 42 53 63 74 85 95 109 6 3 1 501 4 2 5 209 10 8 10 40[分析]首先我们将图构建出来我们将m次询问按权值从小到大排序后: 1 4 2 5 209 10 8 10

【链表】2017多校训练3 HDU 6058 Kanade&#39;s sum

acm.hdu.edu.cn/showproblem.php?pid=6058 [题意] 给定一个排列,计算 [思路] 计算排列A中每个数的贡献,即对于每个ai,计算有ni个区间满足ai是区间中的第k大,那么ai对答案的贡献就是ai*ni 以ai为起点,统计ai右边离ai最近的,比ai大的k个数的位置 同理统计左边的位置,组合得到答案 关键是得到比ai大的离ai最近的k个数的位置 因为是排列,所以每个数都不相等,可以记录每个数的位置,然后从小到大枚举ai,这样维护一个双向链表,保证链表中的数就是

hdu6103[尺取法] 2017多校6

/*hdu6103[尺取法] 2017多校6*/ #include <bits/stdc++.h> using namespace std; int T, m; char str[20005]; void solve() { int ans = 0; int n = strlen(str); for (int i = 0; i < n; i++) { int l = 0, r = 0, p1 = i, p2 = i + 1, cost = 0; while (p1 - r >= 0

2017 多校训练 1006 Function

Function Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others)Total Submission(s): 273    Accepted Submission(s): 99 Problem Description You are given a permutation a from 0 to n−1 and a permutation b from 0 to m−1. De

2017多校Round3(hdu6056~hdu6066)

补题进度:7/11 1001 待填坑 1002 待填坑 1003(set) 题意: 给定长度为n(n<=5e5)的数组(是n的一个排列)和一个整数k(k<=80),f[l,r]定义为区间[l,r]内的第k大的数,求所有区间的f值的和 分析: 倒过来考虑,考虑每个数a[i]对答案有多少贡献 将n个数字从大到小依次插入对应位置,已经插入的当作障碍点(可以用set来维护) 那么对于一个i,可以枚举其左边有x个右边有k-x个去统计答案,因为k<=80,所以是OK的 注意边界情况 时间复杂度O(n