首页 > 其他分享 >CWOI DS 专题

CWOI DS 专题

时间:2023-09-22 09:00:27浏览次数:30  
标签:ch int sqrt id CWOI 专题 gc ans DS

O - 你的名字。

哎,卡常。

考虑根号分治。当 \(k\le T\) 时我们对每种可能的 \(k\) 预处理 \(a_i\bmod k\),然后分成 \(\sqrt{n}\) 块,每块块内维护前后缀最小值,对所有块再跑 ST 表。当询问两端点在同一块内时暴力查询,不在同一块内时分成整块和散块 \(\mathcal{O}(1)\) 查询,复杂度 \(\mathcal{O}(T(n+\sqrt{n}\log\sqrt{n})+\sum[k_i\le T])\);当 \(k>T\) 时发现 \(\dfrac{V}{k}\) 不会太大,可以枚举 \(i\),每次只考虑 \(a_j\in[ik,(i+1)k)\) 的位置,然后类似上述做法处理。

发现此时空间复杂度是 \(\mathcal{O}(\dfrac{mV}{T})\) 级别的,不太能行。不妨转为枚举 \(ik\),此时不需要额外开空间。同时由于本题求最小值,我们只用保证 \(a_j\ge ik\) 即可,于是可以从大到小枚举,每次逐渐加入,单次修改复杂度为 \(\mathcal{O}(\sqrt{n}+(1+2+4+\ldots \sqrt{n}))=\mathcal{O}(\sqrt{n})\) 级别,总复杂度 \(\mathcal{O}(n\sqrt{n}+V\ln V+\sum[k_i>T])\)。

注意本题非常卡常,有几个细节需要注意:

  • 适当调整块长,经试验取在 630 左右最优;

  • 快读,以及其他所有常用、基本的卡常技巧,以及不要用 vector;

  • 玄学的估价函数:可以大概预估一下两种方法需要的大概时间,然后考虑选哪种;

点击查看代码
#include<bits/stdc++.h>
using namespace std;
const int inf=1e9;
struct IO {
#define MAXSIZE (1 << 20)
#define isdigit(x) (x >= '0' && x <= '9')
  char buf[MAXSIZE], *p1, *p2;
  char pbuf[MAXSIZE], *pp;
#if DEBUG
#else
  IO() : p1(buf), p2(buf), pp(pbuf) {}

  ~IO() { fwrite(pbuf, 1, pp - pbuf, stdout); }
#endif
  char gc() {
#if DEBUG
    return getchar();
#endif
    if (p1 == p2) p2 = (p1 = buf) + fread(buf, 1, MAXSIZE, stdin);
    return p1 == p2 ? ' ' : *p1++;
  }
  bool blank(char ch) {
    return ch == ' ' || ch == '\n' || ch == '\r' || ch == '\t';
  }
  template <class T>
  void read(T &x) {
    double tmp = 1;
    bool sign = 0;
    x = 0;
    char ch = gc();
    for (; !isdigit(ch); ch = gc())
      if (ch == '-') sign = 1;
    for (; isdigit(ch); ch = gc()) x = x * 10 + (ch - '0');
    if (ch == '.')
      for (ch = gc(); isdigit(ch); ch = gc())
        tmp /= 10.0, x += tmp * (ch - '0');
    if (sign) x = -x;
  }
  void read(char *s) {
    char ch = gc();
    for (; blank(ch); ch = gc())
      ;
    for (; !blank(ch); ch = gc()) *s++ = ch;
    *s = 0;
  }
  void read(char &c) {
    for (c = gc(); blank(c); c = gc())
      ;
  }
  void push(const char &c) {
#if DEBUG
    putchar(c);
#else
    if (pp - pbuf == MAXSIZE) fwrite(pbuf, 1, MAXSIZE, stdout), pp = pbuf;
    *pp++ = c;
#endif
  }
  template <class T>
  void write(T x) {
    static T sta[35];
    T top = 0;
    do {
      sta[top++] = x % 10, x /= 10;
    } while (x);
    while (top) push(sta[--top] + '0');
  }
  template <class T>
  void write(T x, char lastChar) {
    write(x), push(lastChar);
  }
} io;
struct Que{
	int l,r,k,id;
}q[300005];
inline int cmpq(Que x,Que y){
	return x.k<y.k;
}
int n,m,V,T,a[300005],b[300005],c[300005],ans[300005],lv[100005],rv[100005],lp[100005],rp[100005];
int siz,num,bel[300005],L[635],R[635],pr[635][635],sf[635][635],Log[635],f[12][635];
inline int qry(int l,int r){
	int il=bel[l],ir=bel[r],o=Log[(ir-1)-(il+1)+1];
	if(ir-il==1)return min(sf[il][l-L[il]+1],pr[ir][r-L[ir]+1]);
	return min({sf[il][l-L[il]+1],pr[ir][r-L[ir]+1],f[o][(il+1)],f[o][(ir-1)-(1<<o)+1]});
}
inline void solve(int k){
	for(int i=1;i<=n;++i)c[i]=a[i]%k;
	for(int i=1;i<=num;++i){
		pr[i][1]=c[L[i]];
		for(int j=L[i]+1;j<=R[i];++j)pr[i][j-L[i]+1]=min(pr[i][j-L[i]],c[j]);
		sf[i][R[i]-L[i]+1]=c[R[i]];
		for(int j=R[i]-1;j>=L[i];--j)sf[i][j-L[i]+1]=min(sf[i][j-L[i]+2],c[j]);
	}
	for(int i=1;i<=num;++i)f[0][i]=pr[i][R[i]-L[i]+1];
	for(int j=1;j<=Log[num];++j){
		for(int i=1;i+(1<<j)-1<=num;i++){
			f[j][i]=min(f[j-1][i],f[j-1][i+(1<<(j-1))]);
		}
	}
	for(int x=lv[k];x<=rv[k];++x)if(q[x].r-q[x].l+1>siz)ans[q[x].id]=qry(q[x].l,q[x].r);
}
inline int cmpa(int x,int y){
	return a[x]>a[y];
}
signed main(){
	io.read(n),io.read(m),siz=630,num=(n+siz-1)/siz;
	for(int i=1;i<=n;++i)bel[i]=(i-1)/siz+1;
	for(int i=1;i<=num;++i)L[i]=(i-1)*siz+1,R[i]=i*siz;
	R[num]=n;
	Log[1]=0;for(int i=2;i<=num+2;++i)Log[i]=Log[i>>1]+1;
	for(int i=1;i<=n;++i)io.read(a[i]),V=max(V,a[i]),b[i]=i;
	for(int i=1;i<=m;++i)io.read(q[i].l),io.read(q[i].r),io.read(q[i].k),q[i].id=i,ans[i]=inf;
	sort(q+1,q+m+1,cmpq);sort(b+1,b+n+1,cmpa);
	for(int i=1;i<=n;++i)lp[a[b[i]]]=(lp[a[b[i]]]?lp[a[b[i]]]:i),rp[a[b[i]]]=i;
	for(int i=1;i<=m;++i){
		int l=q[i].l,r=q[i].r,k=q[i].k,id=q[i].id;T=max(T,k);
		if(r-l+1<=siz){
			for(int j=l;j<=r;++j)ans[id]=min(ans[id],a[j]%k);
			continue;
		}
		lv[k]=(lv[k]?lv[k]:i),rv[k]=i;
	}
	int w=3*n+siz*Log[siz]-n*siz/m;
	for(int i=1;i<=T;++i)if(w<2.7*(V/i-1)*(rv[i]-lv[i]+1))solve(i),lv[i]=0;
	for(int i=1;i<=num;++i)for(int j=1;j<=R[i]-L[i]+1;++j)pr[i][j]=sf[i][j]=inf;
	for(int j=0;j<=Log[num];++j)for(int i=1;i+(1<<j)-1<=num;++i)f[j][i]=inf;
	for(int i=V;i>=1;i--){
		for(int x=lp[i];x<=rp[i];++x){
			int p=b[x],id=bel[p];
			for(int i=p;i<=R[id];++i)pr[id][i-L[id]+1]=a[p];
			for(int i=L[id];i<=p;++i)sf[id][i-L[id]+1]=a[p];
			for(int j=0;j<=Log[num];++j){
				int lt=max(1,id-(1<<j)+1),rt=min(id,num-(1<<j)+1);
				for(int i=lt;i<=rt;++i)f[j][i]=a[p];
			}
		}
		for(int j=1;j*j<=i;++j){
			if(i%j)continue;
			if(lv[j]){
				for(int x=lv[j];x<=rv[j];++x){
					int l=q[x].l,r=q[x].r,id=q[x].id;
					if(r-l+1>siz)ans[id]=min(ans[id],qry(l,r)-i);
				}
			}
			if(lv[i/j]&&i/j!=j){
				for(int x=lv[i/j];x<=rv[i/j];++x){
					int l=q[x].l,r=q[x].r,id=q[x].id;
					if(r-l+1>siz)ans[id]=min(ans[id],qry(l,r)-i);
				}
			}
		}
	}
	for(int i=1;i<=m;++i){
		int l=q[i].l,r=q[i].r,id=q[i].id;
		if(r-l+1>siz&&lv[q[i].k])ans[id]=min(ans[id],qry(l,r));
	}
	for(int i=1;i<=m;++i)io.write(ans[i],'\n');
	return 0;
}

标签:ch,int,sqrt,id,CWOI,专题,gc,ans,DS
From: https://www.cnblogs.com/xx019/p/17720565.html

相关文章

  • 【Android面试】2023最新大厂面试专题一:关于HashMap那些事儿
    1、 请说一说HashMap,SparseArrary原理,SparseArrary相比HashMap的优点、ConcurrentHashMap如何实现线程安全?这道题想考察什么?1、HashMap,SparseArrary基础原理?2、SparseArrary相比HashMap的优点是什么?3、ConcurrentHashMap如何实现线程安全?考察的知识点HashMap,SparseArrary、Concurre......
  • CF671D Roads in Yusland
    1D8ya。设\(f_{u,i}\)表示覆盖了\(u\)子树并且向上覆盖到了深度为\(i\)的最小代价。考虑合并儿子\(v\):\[f'_{u,i}\gets\min\left(f_{u,i}+\min\limits_{j=1}^nf_{v,j},f_{v,i}+\min\limits_{j=1}^nf_{u,j}\right)\]相当于区间加,单点取\(\min\),区间求最小值。直接......
  • Denpendcy Injection 8.0新功能——KeyedService
    DenpendcyInjection8.0新功能——KeyedService本文只介绍.NETDenpendcyInjection8.0新功能——KeyedService,假定读者已熟练使用之前版本的功能。注册带Key的类8.0之前,注册一个类往往是AddSingleton<IFoo,Foo>(),8.0添加了一个新功能:“可以注册一个带Key的类”AddKeyedSin......
  • CocoaPods 在iOS开发中养活了这么多项目,它到底是个啥? | 京东云技术团队
    对于iOS开发者而言,CocoaPods并不陌生,通过pod相关的命令操作,就可以很方便的将项目中用到的三方依赖库资源集成到项目环境中,大大的提升了开发的效率。CocoaPods作为iOS项目的包管理工具,它在命令行背后做了什么操作?而又是通过什么样的方式将命令指令声明出来供我们使用的?这些实现的背......
  • CocoaPods 在iOS开发中养活了这么多项目,它到底是个啥?
    对于iOS开发者而言,CocoaPods并不陌生,通过pod相关的命令操作,就可以很方便的将项目中用到的三方依赖库资源集成到项目环境中,大大的提升了开发的效率。CocoaPods作为iOS项目的包管理工具,它在命令行背后做了什么操作?而又是通过什么样的方式将命令指令声明出来供我们使用的?这些实现的背......
  • # yyds干货盘点 # 系统提取的部分数据存在异常,Python填充有其他更简单的方法么?
    大家好,我是皮皮。一、前言前几天在Python最强王者群【wen】问了一个Python自动化办公的问题,一起来看看吧。请教问题:友信平台因为系统提取的部分数据存在异常,导出的数据经常缺失客户名,但是客户账号是准确的,如果实现客户名自动填充?解决思路:1单独生成客户账号和客户名的表格,两个表格进......
  • impdp报ORA-39405,手动更新DST v41版本
    前言业务部门使用impdp进行数据加载时报错,错误信息如下所示。ORA-39405:OracleDataPumpdoesnotsupportimportingfromasourcedatabasewithTSTZversion41intoatargetdatabasewithTSTZversion32.错误提示信息已经非常显示,源端数据库的TSTZ版本为41......
  • [878] Records of LandInsight
    1.Arcpy:(1)TableToExcelarcpy.conversion.TableToExcel(Input_Table=r"S:\TRAINING\Bingnan\Default.gdb\LI_CLR_VIC",Output_Excel_File=r"D:\OneDrive\OneDrive-LandInsightResources\Documents\ArcGIS\Projects\MyProject_2......
  • 【专题】2022年中国跨境电商行业研究报告PDF合集分享(附原数据表)
    报告链接:http://tecdat.cn/?p=32044近年来,我国的跨境电子商务发展迅速,在过去五年中,其贸易额增长率达到了16.2%,已经成为稳定对外贸易的一支重要力量。阅读原文,获取专题报告合集全文,解锁文末52份跨境电商行业相关报告。一方面,随着跨境电子商务的发展,跨境电子商务的监管政策得到了......
  • #yyds干货盘点# LeetCode程序员面试金典:二叉搜索树的最近公共祖先
    题目:给定一个二叉搜索树,找到该树中两个指定节点的最近公共祖先。百度百科中最近公共祖先的定义为:“对于有根树T的两个结点p、q,最近公共祖先表示为一个结点x,满足x是p、q的祖先且x的深度尽可能大(一个节点也可以是它自己的祖先)。”例如,给定如下二叉搜索树: root= [6,2......