• [CSP-S模拟测试]:养花(分块)


    题目描述

    小$C$在家种了$n$盆花,每盆花有一个艳丽度$a_i$。
    在接下来的$m$天中,每天早晨他会从一段编号连续的花中选择一盆摆放在客厅,并在晚上放回。同时每天有特定的光照强度$k_i$,如果这一天里摆放在客厅的花艳丽度为$x$,则他能获得的喜悦度为$xmod k_i$。
    他希望知道,每一天他能获得的最大喜悦度是多少。


    输入格式

    数据第一行包含两个正整数$n,m$。
    接下来一行$n$个正整数,第$i$个数$a_i$表示第$i$盆花的艳丽度。
    接下来$m$行,每行三个正整数$l_i,r_i,k_i$,表示选花区间和光照强度。


    输出格式

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


    样例

    样例输入:

    5 5
    1 2 3 4 5
    1 3 2
    1 3 3
    1 4 4
    5 5 5
    3 5 3

    样例输出:

    1
    2
    3
    0
    2


    数据范围与提示

    对于$20\%$的数据,$n,mleqslant 4,000$。
    对于$40\%$的数据,$n,mleqslant 50,000$。
    对于另外$20\%$的数据,$a_ileqslant 300$。
    对于$100\%$的数据,$n,m,a_i,k_ileqslant {10}^5$。


    题解

    好久没有打过分块了,你看着道题就是一个分块。

    至于题解上说的时间复杂度$Theta(kln k)$我也不清楚是怎么做的。

    我就是对于每一块维护对于每一个模数的最大值。

    这道题的数据除了点锅,$k_i$出现了$100001$,但是标程只扫到了$100000$,所以如果数据没有更新的话你拿到$60$分是对的,对于打主席树的小盆友,我也没辙了。

    时间复杂度:$Theta(frac{n^2}{1000})$。

    期望得分:$100$分。

    实际得分:$100$分。


    代码时刻

    #include<bits/stdc++.h>
    using namespace std;
    int n,m,t;
    int a[100010];
    int s[100010];
    int sum[1000][100010];
    void pre_work()
    {
    	for(int i=1;i<=(n-1)/t+1;i++)
    	{
    		memset(s,0,sizeof(s));
    		for(int j=(i-1)*t+1;j<=min(i*t,n);j++)s[a[j]]=a[j];
    		for(int j=1;j<=100001;j++)s[j]=max(s[j],s[j-1]);
    		for(int j=1;j<=100001;j++)
    			for(int k=0;k<=100001;k+=j)
    				sum[i][j]=max(sum[i][j],s[min(j+k-1,100001)]-k);
    	}
    }
    int getans(int l,int r,int k)
    {
    	int res=0;
    	int lft=(l-1)/t+1;
    	int rht=(r-1)/t+1;
    	for(int i=lft+1;i<=rht-1;i++)res=max(res,sum[i][k]);
    	for(int i=l;i<=min(lft*t,r);i++)res=max(res,a[i]%k);
    	for(int i=max((rht-1)*t+1,l);i<=r;i++)res=max(res,a[i]%k);
    	return res;
    }
    int main()
    {
    	scanf("%d%d",&n,&m);
    	t=1000;
    	for(int i=1;i<=n;i++)scanf("%d",&a[i]);
    	pre_work();
    	while(m--)
    	{
    		int l,r,k;
    		scanf("%d%d%d",&l,&r,&k);
    		printf("%d
    ",getans(l,r,k));
    	}
    	return 0;
    }
    

    rp++

  • 相关阅读:
    设计模式详解(一):单例模式
    6大设计原则详解(二)
    6大设计原则详解(一)
    Java线程池的创建详解
    Jquery实现表单动态加减、ajax表单提交
    Java并发编程:浅析几种线程安全模型 [转]
    Java并发之线程状态及Thread常用方法
    Java并发编程:CountDownLatch、CyclicBarrier和 Semaphore[转]
    Java并发之synchronized使用
    Java分布式锁之数据库方式实现
  • 原文地址:https://www.cnblogs.com/wzc521/p/11574903.html
Copyright © 2020-2023  润新知