#46. 【清华集训2014】玄学

一开始脑子进水了、把这题想简单了、复杂度算错了、每次都用nlogn的时间修改、而且还狂写STL、然后就直播自爆8小时QAQ。
先挂个5分代码。
#include<cstdio>
#include<cstring>
#include<iostream>
#include<vector>
#include<algorithm>
#include<set> 
using namespace std;
#define rep(i,j,k) for(i=j;i<=k;++i)
#define per(i,j,k) for(i=j;i>=k;--i)
#define pii pair<int,int>
#define mkp make_pair
#define X first
#define Y second
#define LL long long
LL n,M,m,w[100005],mx,ans;
struct MODIFY{LL I,J,A,B;}mdf0,sb;
vector<MODIFY>T[7000000];
LL qA,qB;
void write(LL l,LL r,LL num){
	printf("%lld: ",num);
	vector<MODIFY>::iterator ii;
	for(ii=T[num].begin();ii!=T[num].end();++ii)
		printf("%lld %lld %lld %lld     ",ii->I,ii->J,ii->A,ii->B);
	puts("");
	if(l==r)return;
	LL mid=l+r>>1;
	write(l,mid,num<<1);write(mid+1,r,num<<1|1);
}
bool cmp1(MODIFY x,MODIFY y){
	return x.I<y.I;
}
bool cmp2(MODIFY x,MODIFY y){
	return x.J<y.J;
}
void build(LL l,LL r,LL num){
	T[num].push_back(mdf0);T[num].push_back(sb);
	if(l==r)return;
	LL mid=l+r>>1LL;
	build(l,mid,num<<1LL),build(mid+1LL,r,num<<1LL|1LL);
}
void ins(MODIFY in,LL x,LL l,LL r,LL num){
	vector<MODIFY>::iterator ll,rr,ii;
	ll=--upper_bound(T[num].begin(),T[num].end(),(MODIFY){in.I,0LL,0LL,0LL},cmp1);
	LL tmpi=ll->I,tmpj=ll->J,tmpa=ll->A,tmpb=ll->B;
	if(tmpi<in.I)T[num].insert(ll,(MODIFY){tmpi,in.I-1,tmpa,tmpb});
	if(tmpj>=in.J){
		rr=upper_bound(T[num].begin(),T[num].end(),(MODIFY){tmpi,0LL,0LL,0LL},cmp1);
		if(tmpj>in.J)T[num].insert(rr,(MODIFY){in.J+1,tmpj,tmpa,tmpb});
		rr=lower_bound(T[num].begin(),T[num].end(),(MODIFY){0LL,tmpj,0LL,0LL},cmp2);
		*rr=(MODIFY){in.I,in.J,in.A*tmpa%M,(in.B+in.A*tmpb)%M};
	}
	else{
		rr=lower_bound(T[num].begin(),T[num].end(),(MODIFY){0LL,in.J,0LL,0LL},cmp2);
		if(tmpj>in.J)T[num].insert(rr,(MODIFY){in.J+1,tmpj,tmpa,tmpb});
		ll=--upper_bound(T[num].begin(),T[num].end(),(MODIFY){tmpi,0LL,0LL,0LL},cmp1);
		rr=lower_bound(T[num].begin(),T[num].end(),(MODIFY){0LL,in.J,0LL,0LL},cmp2);
		*ll=(MODIFY){in.I,ll->J,in.A*ll->A%M,(in.B+in.A*ll->B)%M};
		*rr=(MODIFY){rr->I,in.J,in.A*rr->A%M,(in.B+in.A*rr->B)%M};
		for(ii=++ll;ii!=rr;++ii)
			*ii=(MODIFY){ii->I,ii->J,in.A*ii->A%M,(in.B+in.A*ii->B)%M};
	}
	if(l==r)return;
//	write(l,r,num);
	LL mid=l+r>>1LL;
	if(x>mid)ins(in,x,mid+1,r,num<<1LL|1LL);
	else ins(in,x,l,mid,num<<1LL);
}
void query(LL L,LL R,LL x,LL l,LL r,LL num){
	if(L<=l&&r<=R){
		vector<MODIFY>::iterator ii;
		ii=lower_bound(T[num].begin(),T[num].end(),(MODIFY){0LL,x,0LL,0LL},cmp2);
		qA=ii->A*qA%M;qB=(ii->B+ii->A*qB)%M;
		return;
	}
	LL mid=l+r>>1LL;
	if(L<=mid)query(L,R,x,l,mid,num<<1LL);
	if(R>mid)query(L,R,x,mid+1LL,r,num<<1LL|1LL);
}
int main(){
	freopen("r.in","r",stdin);
	freopen("w.out","w",stdout);
	LL flg,o,Q,i,j,x,y;
	scanf("%lld%lld%lld",&flg,&n,&M);flg&=1;
	rep(i,1,n)scanf("%lld",&w[i]);
	scanf("%lld",&Q);mx=min(100000LL,Q);
	mdf0=(MODIFY){1LL,n,1LL,0LL};sb=(MODIFY){n+1,n+1,0LL,0LL};
	build(1LL,mx,1LL);
	while(Q--){
		scanf("%lld%lld%lld%lld",&o,&i,&j,&x);
		if(flg)i^=ans,j^=ans;
		if(o==1){
			scanf("%lld",&y);
			ins((MODIFY){i,j,x,y},++m,1LL,mx,1LL);
		}
		else{
			qA=1;qB=0;if(flg)x^=ans;
			query(i,j,x,1LL,mx,1LL);
			printf("%lld\n",ans=(qA*w[x]+qB)%M);
		}
	}
	write(1,mx,1);
	return 0; 
}
到现在才知道这题的思路用多恐怖。
实际上 这题是修改log,查询log^2的。
虽然这题要求强制在线,但是 相当于 离线。由于每次的query只会对已修改的操作,所以可以 分步进行预处理 。每次对一个l==r的节点x修改,然后对包含它的节点进行线段树合并,当且仅当这个节点的r恰好为x的r(或l)。
然后查询时使用二分查找。
最后注意对STL say goodbye!!!
AC代码:
#include<cstdio>
#include<cstring>
#include<iostream>
#include<vector>
#include<algorithm>
#include<set> 
using namespace std;
#define rep(i,j,k) for(i=j;i<=k;++i)
#define per(i,j,k) for(i=j;i>=k;--i)
#define LL long long
#define pll pair<LL,LL>
#define mkp make_pair
#define X first
#define Y second
LL n,M,m,w[100000],mx,ans;
struct MODIFY{LL I,J,A,B;}mdf,qj[7000000];
pll T[400000];LL id;
LL L,R,wz,qA,qB;
void ins(LL l,LL r,LL num){
	if(l==r){
		LL l0=id+1;
		if(mdf.I>1)qj[++id]=(MODIFY){1,mdf.I-1,1,0};
		qj[++id]=mdf;
		if(mdf.J<n)qj[++id]=(MODIFY){mdf.J+1,n,1,0};
		T[num]=mkp(l0,id);return;
	}
	LL mid=l+r>>1;
	if(m>mid)ins(mid+1,r,num<<1|1);
	else ins(l,mid,num<<1);
	if(m==r){
		LL l0=id+1,k=1,l1=T[num<<1].X,l2=T[num<<1|1].X;
		while(k<=n){
			if(qj[l1].J<qj[l2].J){
				qj[++id]=(MODIFY){k,qj[l1].J,qj[l1].A*qj[l2].A%M,(qj[l1].B*qj[l2].A+qj[l2].B)%M};
				k=qj[l1].J+1;++l1;
			}
			else if(qj[l1].J>qj[l2].J){
				qj[++id]=(MODIFY){k,qj[l2].J,qj[l1].A*qj[l2].A%M,(qj[l1].B*qj[l2].A+qj[l2].B)%M};
				k=qj[l2].J+1;++l2;
			}
			else{
				qj[++id]=(MODIFY){k,qj[l1].J,qj[l1].A*qj[l2].A%M,(qj[l1].B*qj[l2].A+qj[l2].B)%M};
				k=qj[l1].J+1;++l1;++l2;
			}
		}
		T[num]=mkp(l0,id);
	}
}
bool cmp(MODIFY u,MODIFY v){
	return u.J<v.J;
}
void query(LL l,LL r,LL num){
	if(L<=l&&r<=R){
		int tmp=lower_bound(qj+T[num].X,qj+T[num].Y+1,(MODIFY){0LL,wz,0LL,0LL},cmp)-qj;
		qA=qj[tmp].A*qA%M;qB=(qj[tmp].A*qB+qj[tmp].B)%M;
		return;
	}
	int mid=l+r>>1;
	if(L<=mid)query(l,mid,num<<1);
	if(R>mid)query(mid+1,r,num<<1|1);
}
int main(){
	LL flg,i,Q,o,j,x,y;
	scanf("%lld%lld%lld",&flg,&n,&M);flg&=1;
	rep(i,1,n)scanf("%lld",&w[i]);
	scanf("%lld",&Q);mx=min(100000LL,Q);
	while(Q--){
		scanf("%lld%lld%lld%lld",&o,&i,&j,&x);
		if(flg)i^=ans,j^=ans;
		if(o==1){
			scanf("%lld",&y);
			mdf=(MODIFY){i,j,x,y};++m;
			ins(1LL,mx,1LL);
		}
		else{
			qA=1;qB=0;L=i;R=j;wz=x;if(flg)wz^=ans;
			query(1LL,mx,1LL);
			printf("%lld\n",ans=(qA*w[wz]+qB)%M);
		}
	}
	return 0; 
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: source.list是Linux系统中一个重要的配置文件,用于指定软件包管理器(如apt)从哪个源(服务器)下载软件包。清华源是中国科学技术大学计算机技术研究所开设的开源软件镜像站点之一,被广泛用于国内用户进行软件下载和更新。 将清华源加入source.list的配置中,可以提高软件包管理器的下载速度和可用性,特别是在国内用户访问国外服务器受限的情况下。通过使用清华源,可以减少从国外服务器下载软件包的延迟和网络传输的消耗,提高软件安装和更新的效率。 要使用清华源,首先需要在source.list文件中添加相应的源地址。在Ubuntu系统中,可以通过执行以下命令打开source.list文件: ``` sudo gedit /etc/apt/sources.list ``` 在打开的文件中找到已有的源地址行,一般以`deb`开头,将其注释或删除。然后在文件中添加以下清华源地址: ``` deb https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ focal main restricted universe multiverse deb https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ focal-updates main restricted universe multiverse deb https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ focal-backports main restricted universe multiverse deb https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ focal-security main restricted universe multiverse ``` 保存并关闭文件后,执行更新命令以使更改生效: ``` sudo apt update ``` 之后就可以通过软件包管理器从清华源下载和更新软件包了。 总之,使用清华源可以提高国内用户下载和更新软件包的速度和稳定性,是国内用户优化Linux系统的常用方法之一。 ### 回答2: 源列表是一个存储软件包下载地址的配置文件,用于系统更新和安装软件。清华源是清华大学提供的一个软件镜像站点,可以在中国内地快速下载各种软件包。 清华源作为中国内地最大的开源软件镜像站之一,为国内用户提供了优质、高速的软件下载服务。通过将软件包和镜像存放在清华源上,用户可以通过源列表将清华源加入到系统的软件源列表中,从而在系统更新和安装软件时可以直接从清华源上下载,加快下载速度,同时减轻了国外软件源的压力。 清华源的优势不仅在于下载速度快,还可以为用户提供更加稳定和安全的下载环境。清华大学作为一个知名的高等学府,拥有先进的硬件设备和强大的网络实力,能够保证用户在下载软件时的稳定性和安全性,为用户提供一个可信赖的软件下载平台。 通过将清华源添加到源列表中,用户可以在进行系统更新和安装软件时,选择从清华源上下载软件包,以提高下载速度和下载稳定性。这对于有着网络环境限制的用户来说,尤为重要,可以更快更稳定地获取所需的软件包。 总之,source.list清华源是一个可以通过将清华源添加到源列表中的方式,让用户能够更快速、更稳定地下载所需软件包的配置文件。它为中国内地的用户提供了一个可信赖、高速的软件下载平台,帮助用户更方便地进行系统更新和软件安装。 ### 回答3: source.list清华源是Ubuntu系统中的软件源列表,它包含了从清华大学镜像站下载软件所需的服务器地址信息。清华大学作为国内知名的高等学府,拥有强大的计算机资源和网络优势,因此其镜像站提供了许多流行的开源软件的下载服务。 使用source.list清华源的好处是能够提高软件下载的速度和稳定性。由于清华大学资源丰富,其镜像站所提供的软件下载通常速度较快,用户可以在较短的时间内获取所需的软件包。同时,清华源通常能够及时更新软件包,用户可以始终使用最新版本的软件,享受最新功能和修复的好处。 配置source.list清华源也很简单。首先,用户需要编辑source.list文件,将原来的软件源地址替换为清华源的地址。然后,保存修改后的文件并更新软件包列表。配置完成后,用户便可以通过清华源下载和更新软件了。 总而言之,source.list清华源是Ubuntu系统中使用的一个软件源列表,它提供了清华大学镜像站的服务器地址信息。使用清华源可以提高软件下载的速度和稳定性,帮助用户更快地获取所需的软件,并始终使用最新版本的软件。配置source.list清华源也非常简单,用户只需简单地编辑并更新软件包列表即可享受这些好处。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值