模拟测试49

这次考试题还是蛮好的,只是人很水啊

T1

考场思路:

1.每次询问离线出来,再对于每一个k进行操作,klnk枚举区间,再利用主席树查前驱,期望时间复杂度O(n*log(n)^2)但可以被卡到(n^2*log(n))(对于k极小的询问),如果优化就把k极小的询问预处理?不可实现弃辽

2.分块,不会处理每一块的答案,死了

所以正解还是分块,考虑预处理每一块答案。

对于一个k来说,答案一定是max{i*k~i*k+k-1}(0<=i<=n/k)中每一段的最大值%k,开一个桶维护每一块内的元素,扫一边搞出<=每个数的数直接处理即可。复杂度为O(n*ln(n)*n/S+m*S)当S取sqrt(n*log(n))的时候最小为O(n*sqrt(n*log(n)))

 1 #include<cstdio>
 2 #include<cmath>
 3 #include<iostream>
 4 #define N 100001
 5 #define sN 105
 6 using namespace std;
 7 inline int _max(int a,int b){return a>b?a:b;}
 8 int bl[N+5],ans[sN][N+5],t[N+5],tl[N+5],tot,L[sN],a[N+5];
 9 inline int read()
10 {
11     int x=0,f=1;char c=getchar();
12     while(c>'9'||c<'0'){if(c=='-')f=-1;c=getchar();}
13     while(c>='0'&&c<='9')x=x*10+c-48,c=getchar();
14     return x*f;
15 }
16 inline void pre()
17 {
18     int now;
19     for(int i=1;i<=tot;i++)
20     {
21         now=L[i];
22         while(bl[now]==i)t[a[now]]++,tl[a[now]]=a[now],now++;
23         for(int j=1;j<=N;j++)if(!t[j])tl[j]=tl[j-1];now=L[i];
24         for(int j=2;j<=N;j++)
25         {
26             for(int k=j-1;k<=N;k+=j)
27                 ans[i][j]=_max(ans[i][j],(tl[k]%j));
28             ans[i][j]=_max(ans[i][j],(tl[N]%j));
29         }
30         while(bl[now]==i)t[a[now]]--,tl[a[now]]=0,now++;
31     }
32 }
33 inline int query(int l,int r,int k)
34 {
35     int mx=0;
36     if(bl[l]==bl[r])
37     {
38         for(int i=l;i<=r;i++)mx=_max(mx,a[i]%k);
39         return mx;
40     }
41     for(int i=l;bl[i]==bl[l];i++)mx=_max(mx,a[i]%k);
42     for(int i=bl[l]+1;i<bl[r];i++)mx=_max(mx,ans[i][k]);
43     for(int i=r;bl[i]==bl[r];i--)mx=_max(mx,a[i]%k);
44     return mx;
45 }
46 int main()
47 {
48     int n=read(),m=read();
49     int t=sqrt(n*20)+1;
50     for(int i=1;i<=n;i++)
51     {
52         bl[i]=(i-1)/t+1;//printf("%d\n",bl[i]);
53         if(bl[i]!=bl[i-1])L[bl[i]]=i;
54         a[i]=read();
55     }tot=bl[n];pre();
56     while(m--)
57     {
58         int l=read(),r=read(),k=read();
59         printf("%d\n",query(l,r,k));
60     }
61     return 0;
62 }
View Code

T2

n^2思路很简单,但是会被卡空间。

所以换个角度,按x排序。

实际上就是找不断往中间收缩的方案数(感性理解)

考虑处理出前i-1个如何弄第i个,设dp[i][0/1]表示以i为起点往左/右走的方案数

如果i是起点,那么给i加上前面比它小的往右撇的方案即可

如果不是,那么i一定是第二个点,枚举起点和第三个点,给起点加上第三个点的贡献。

得出转移方程:

dp[i][0]+=dp[j][1];(j<i&&y[j]<y[i])

dp[j][1]+=dp[z][1];(j<i&&z>j&&z<i&&y[z]<y[j]&&y[j]<y[i])

 1 #include<cstdio>
 2 #include<algorithm>
 3 #define FH_SB 6005
 4 using namespace std;
 5 const int mod=1e9+7;
 6 int dp[FH_SB][2],s[FH_SB];
 7 struct node{
 8     int fh,sb;
 9     inline void init(){scanf("%d%d",&fh,&sb);}
10     friend bool operator <(const node a,const node b){ return a.fh<b.fh;}
11 }a[FH_SB];
12 int main()
13 {
14     int n,ans=0;scanf("%d",&n);
15     for(int i=1;i<=n;i++)a[i].init();
16     sort(a+1,a+n+1);
17     for(int i=1;i<=n;i++)
18     {
19         s[i]=1;dp[i][0]++;dp[i][1]++;
20         for(int j=i-1;j;j--) s[j]=(s[j+1]+dp[j][1]*(a[j].sb<a[i].sb))%mod;
21         for(int j=1;j<i;j++)
22         {
23             if(a[j].sb<a[i].sb)(dp[i][0]+=dp[j][1])%=mod;
24             else (dp[j][1]+=s[j+1])%=mod;
25         }
26     }
27     for(int i=1;i<=n;i++)(ans+=(dp[i][0]+dp[i][1])%mod)%=mod;
28     printf("%d\n",ans-n);
29 }
View Code

 

T3不会,咕了。

 

转载于:https://www.cnblogs.com/hzoi-kx/p/11566792.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
SQLAlchemy 是一个 SQL 工具包和对象关系映射(ORM)库,用于 Python 编程语言。它提供了一个高级的 SQL 工具和对象关系映射工具,允许开发者以 Python 类和对象的形式操作数据库,而无需编写大量的 SQL 语句。SQLAlchemy 建立在 DBAPI 之上,支持多种数据库后端,如 SQLite, MySQL, PostgreSQL 等。 SQLAlchemy 的核心功能: 对象关系映射(ORM): SQLAlchemy 允许开发者使用 Python 类来表示数据库表,使用类的实例表示表中的行。 开发者可以定义类之间的关系(如一对多、多对多),SQLAlchemy 会自动处理这些关系在数据库中的映射。 通过 ORM,开发者可以像操作 Python 对象一样操作数据库,这大大简化了数据库操作的复杂性。 表达式语言: SQLAlchemy 提供了一个丰富的 SQL 表达式语言,允许开发者以 Python 表达式的方式编写复杂的 SQL 查询。 表达式语言提供了对 SQL 语句的灵活控制,同时保持了代码的可读性和可维护性。 数据库引擎和连接池: SQLAlchemy 支持多种数据库后端,并且为每种后端提供了对应的数据库引擎。 它还提供了连接池管理功能,以优化数据库连接的创建、使用和释放。 会话管理: SQLAlchemy 使用会话(Session)来管理对象的持久化状态。 会话提供了一个工作单元(unit of work)和身份映射(identity map)的概念,使得对象的状态管理和查询更加高效。 事件系统: SQLAlchemy 提供了一个事件系统,允许开发者在 ORM 的各个生命周期阶段插入自定义的钩子函数。 这使得开发者可以在对象加载、修改、删除等操作时执行额外的逻辑。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值