zoukankan      html  css  js  c++  java
  • 2018 雅礼集训 DAY1T1 养花

    考试拿两年前的雅礼集训题考,自闭了。

    mdnmd,这就全都不会做呗。

    desprition

    C 在家种了 (n) 盆花, 每盆花有一个艳丽度 (a_i). 在接下来的 m 天中, 每天早晨他会从一段编号连续的花中选择一盆摆放在客厅, 并在晚上放回 同时每天有特定的光

    照强度 (k_i), 如果这一天里摆放在客厅的花艳丽度为 (x) , 则他能获得的喜悦度为 (x mod k_i). 他希望知道, 每一天他能获得的最大喜悦度是多少.

    Input Format

    数据第一行包含两个正整数 (n), $ m$ . 接下来一行 (n) 个正整数, 第 (i) 个数 (a_i) 表示第 (i) 盆花的艳丽度.

    接下来 (m) 行, 每行三个正整数 (l_i) (r_i) $ k_i$, 表示选花区间和光照强度

    Output Format

    输出 m 行, 每行一个整数, 表示最大喜悦度

    Constraints

    对于 20% 的数据, (n, m ≤ 4000).

    对于 40% 的数据, (n, m ≤ 50000).

    对于另外 20% 的数据, (a_i ≤ 300).

    对于 100% 的数据, (n, m, a_i , k_i ≤ 10^5)

    sloution

    讲个笑话,正解是分块。

    我们可以考虑预处理出对于每个模数,每个块的答案。

    这个预处理大概可以做到 (O(n + kln k))

    我们要求的是 形如 ([ak,(a+1)k-1]) 这一段区间的最大值 减去 (ak) 的结果。

    那么我们就可以枚举每个 (ak) ,然后算出在这个答案。

    直接暴力枚举的话,复杂度还是比较高,所以求一下前缀最大值就可以。

    询问的复杂度是 (O(ms)) 的,取 (s = sqrt{kln k}) 是达到最优复杂度 (n sqrt{kln k})

    Code

    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    #include<cmath>
    const int N = 1e5+10;
    int n,m,block,l,r,w;
    int sum[1001][N],tong[N],a[N];
    using namespace std;
    inline int read()
    {
    	int s = 0,w = 1; char ch = getchar();
    	while(ch < '0' || ch > '9'){if(ch == '-') w = -1; ch = getchar();}
    	while(ch >= '0' && ch <= '9'){s = s * 10 + ch - '0'; ch = getchar();}
    	return s * w;
    }
    void YYCH()
    {
    	for(int i = 1; i <= (n-1)/block+1; i++)
    	{
    		memset(tong,0,sizeof(tong));
    		for(int j = (i-1) * block + 1; j <= min(i * block, n); j++) tong[a[j]] = a[j];
    		for(int j = 1; j <= 100000; j++) tong[j] = max(tong[j],tong[j-1]);//求前缀最大值
    		for(int j = 1; j <= 100000; j++)//枚举每个模数
    		{
    			for(int k = 0; k <= 100000; k += j)//枚举每个 ak
    			{
    				sum[i][j] = max(sum[i][j],tong[min(k+j-1,100000)]-k);//ak - (a+1)k-1 的最大值
    			}
    		} 
    	}
    }
    int query(int l,int r,int w)//正常的分块询问
    {
    	int ans = 0;
    	int fx = (l-1) / block + 1, fy = (r-1) / block + 1;
    	for(int i = l; i <= min(fx * block, r); i++) ans = max(ans,a[i] % w);
    	for(int i = fx+1; i <= fy-1; i++) ans = max(ans,sum[i][w]);
    	for(int i = max((fy-1) * block + 1,l); i <= r; i++) ans = max(ans,a[i] % w);
    	return ans;
    }
    int main()
    {
    	freopen("flower.in","r",stdin);
    	freopen("flower.out","w",stdout);
    	n = read(); m = read(); block = 1000;
    	for(int i = 1; i <= n; i++) a[i] = read();
    	YYCH();
    	for(int i = 1; i <= m; i++)
    	{
    		l = read(); r = read(); w = read();
    		printf("%d
    ",query(l,r,w));
    	}
    	fclose(stdin); fclose(stdout);
    	return 0;
    }
    
    
  • 相关阅读:
    七、文件的排序、合并和分割
    六、awk编程
    五、sed命令
    四、grep命令
    三、正则表达式
    二、Linux文件系统和文本编辑器
    一、shell基础知识点
    mysql实现交易编码生成(代替oracle的序列)
    新安装Centos无法访问网络
    uiview 动画
  • 原文地址:https://www.cnblogs.com/genshy/p/13876536.html
Copyright © 2011-2022 走看看