ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

省选模拟17

2022-02-17 20:33:48  阅读:146  来源: 互联网

标签:ch return 17 rs 省选 sum tr int 模拟


今天考的不是联考的试题,而是ZZ_zuozhe的题,题目质量好高!!!

第一题,想到了用bitset做,然后发现枚举的有用的只有是1的位,于是想到用set,但是复杂度瓶颈在于转移时的赋值操作,没想到可以用主席树

第二题,妈呀想着是阶乘然后就写成没阶乘了......

第三题,写了个背包,于是只有35分

T1 最短路

发现增加一条路就是将一段连续的1变成0,前面加个1,可以用线段树二分

转移就是直接赋值,这里用dij的时候,用set当堆,这样比较函数比较好写参数可以改

AC_code
#include<bits/stdc++.h>
using namespace std;
#define fo(i,x,y) for(int i=(x);i<=(y);i++)
#define fu(i,x,y) for(int i=(x);i>=(y);i--)
int read(){
	int s=0,t=1;char ch=getchar();
	while(!isdigit(ch)){if(ch=='-')t=-1;ch=getchar();}
	while(isdigit(ch)){s=s*10+ch-'0';ch=getchar();}
	return s*t;
}
const int N=1e5+5;
const int M=2e5+1e3;
const int mod=1e9+7;
int ksm(int x,int y){
	int ret=1;
	while(y){
		if(y&1)ret=1ll*ret*x%mod;
		x=1ll*x*x%mod;y>>=1;
	}return ret;
}
int mo(int x){return x>=mod?x-mod:x;}
int fro[M];int all(int l,int r){if(l==0)return fro[r];return mo(fro[r]-fro[l-1]+mod);}
struct ZXS{
	struct POT{int ls,rs,sum;}tr[M*100];
	int seg;
	int newpot(int x){tr[++seg]=tr[x];return seg;}
	void pushup(int x){
		//if(!tr[x].ls&&!tr[x].rs)return ;
		tr[x].sum=mo(tr[tr[x].ls].sum+tr[tr[x].rs].sum);
	}
	void ins(int &x,int px,int l,int r,int ql,int qr,int v){
		x=newpot(px);if(ql>qr)return ;
		if(ql<=l&&r<=qr){
			tr[x].ls=tr[x].rs=0;
			if(v)tr[x].sum=all(l,r);
			else tr[x].sum=0;
			return ;
		}
		int mid=l+r>>1;
		if(ql<=mid)ins(tr[x].ls,tr[px].ls,l,mid,ql,qr,v);
		if(qr>mid)ins(tr[x].rs,tr[px].rs,mid+1,r,ql,qr,v);
		pushup(x);return ;
	}
	int query_mxlen(int x,int l,int r,int ql){
		if(ql<=l){
			if(tr[x].sum==all(l,r))return r;
			if(l==r||!tr[x].sum)return l-1;
			int mid=l+r>>1;
			if(tr[tr[x].ls].sum==all(l,mid))return query_mxlen(tr[x].rs,mid+1,r,ql);
			else return query_mxlen(tr[x].ls,l,mid,ql);
		}
		if(tr[x].sum==all(l,r))return r;
		if(!tr[x].sum)return ql-1;
		int mid=l+r>>1,ret=0;
		if(ql<=mid)ret=query_mxlen(tr[x].ls,l,mid,ql);
		if(ret==mid||ql>mid)return query_mxlen(tr[x].rs,mid+1,r,ql);
		else return ret;
	}
	bool comp(int x,int y,int l,int r){//x<y true
		if(tr[x].sum==tr[y].sum)return false;
		if(tr[x].sum==all(l,r))return false;
		if(!tr[x].sum)return true;
		if(tr[y].sum==all(l,r))return true;
		if(!tr[y].sum)return false;
		if(l==r)return tr[x].sum<tr[y].sum;
		int mid=l+r>>1;
		if(tr[tr[x].rs].sum==tr[tr[y].rs].sum)return comp(tr[x].ls,tr[y].ls,l,mid);
		else return comp(tr[x].rs,tr[y].rs,mid+1,r);
	}
}zxs;
int rt[N];
int n,m,R=2e5+20,s,t;
bool vis[N],ist[N];
struct node{
	int x;
	bool operator < (node a)const{
		if(zxs.tr[rt[x]].sum==zxs.tr[rt[a.x]].sum)return x<a.x;
		return zxs.comp(rt[x],rt[a.x],1,R);
	}
};
set<node> st;
struct E{int to,nxt,val;}e[M*2];
int head[N],rp;
void add_edg(int x,int y,int z){
	e[++rp].to=y;e[rp].nxt=head[x];
	e[rp].val=z;head[x]=rp;
}
signed main(){
	freopen("hellagur.in","r",stdin);
	freopen("hellagur.out","w",stdout);
	n=read();m=read();
	fro[0]=1;fo(i,1,R)fro[i]=(fro[i-1]+ksm(2,i))%mod;
	fo(i,1,m){
		int x=read(),y=read(),z=read();
		add_edg(x,y,z);add_edg(y,x,z);
		//if(z==0)cerr<<"SB"<<endl;
	}
	s=read();t=read();rt[s]=++zxs.seg;
	fo(i,1,n)if(i!=s)zxs.ins(rt[i],rt[s],1,R,1,R,1);
	st.insert(node{s});ist[s]=true;
	while(st.size()){
		int x=st.begin()->x;st.erase(st.begin());
		if(vis[x])continue;
		vis[x]=true;ist[x]=false;
		for(int i=head[x];i;i=e[i].nxt){
			int y=e[i].to,tmp,r,l=e[i].val;
			if(vis[y])continue;
			r=zxs.query_mxlen(rt[x],1,R,l);
			zxs.ins(tmp,rt[x],1,R,l,r,0);
			zxs.ins(tmp,tmp,1,R,r+1,r+1,1);
			if(zxs.comp(tmp,rt[y],1,R)){
				if(ist[y])st.erase(node{y});
				ist[y]=true;rt[y]=tmp;
				st.insert(node{y});
			}
		}
	}
	if(zxs.tr[rt[t]].sum==all(1,R))printf("-1");
	else printf("%d",zxs.tr[rt[t]].sum);
}

T2 集合

发现有可能的大小是n,n-1,n-2

奇数的话,还有n-3,用异或hash表示

AC_code
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define fo(i,x,y) for(int i=(x);i<=(y);i++)
#define fu(i,x,y) for(int i=(x);i>=(y);i--)
int read(){
	int s=0,t=1;char ch=getchar();
	while(!isdigit(ch)){if(ch=='-')t=-1;ch=getchar();}
	while(isdigit(ch)){s=s*10+ch-'0';ch=getchar();}
	return s*t;
}
const ll inf=1e18;
random_device pyt;
mt19937 you(pyt());
ll rd(ll l,ll r){
	return rand()%inf;
	uniform_int_distribution<> ee(l,r);
	return ee(you)*ee(you);
}
const int N=1e6+5;
int n;
unordered_map<ll,int> mp;
ll vl[100005],val[N],tmp;
int p[100005],cnt,mn[N];
bool vis[N];
void init_p(){
	fo(i,2,n){
		if(!vis[i]){
			p[++cnt]=i;
			vl[cnt]=rd(1,inf);
			mn[i]=cnt;
		}
		for(int j=1;j<=cnt&&i*p[j]<=n;j++){
			vis[i*p[j]]=true;mn[i*p[j]]=j;
			if(i%p[j]==0)break;
		}
	}
}
int ck2(int n){tmp=0;
	fo(i,1,n)tmp^=val[i];
	fo(i,1,n)if(mp.find(tmp^val[i])!=mp.end()&&mp[tmp^val[i]]!=i)return i;
	return false;
}
int ck1(int n){tmp=0;
	fo(i,1,n)tmp^=val[i];
	fo(i,1,n)if((tmp^val[i])==0)return i;
	return false;
}
bool ck0(int n){tmp=0;
	fo(i,1,n)tmp^=val[i];
	return !tmp;
}
signed main(){
	freopen("mountain.in","r",stdin);
	freopen("mountain.out","w",stdout);
	n=read();int res;srand(time(0));
	init_p();
	fo(i,1,n){int now=i;ll hs=0;
		while(now!=1)hs^=vl[mn[now]],now/=p[mn[now]];
		val[i]=val[i-1]^hs;mp[val[i]]=i;
	}
	if(n&1)n--;
	if(ck0(n)){
		printf("%d\n",n);
		fo(i,1,n)printf("%d ",i);
		return 0;
	}
	if(res=ck1(n)){
		printf("%d\n",n-1);
		fo(i,1,n)if(i!=res)printf("%d ",i);
		return 0;
	}
	if(res=ck2(n)){
		printf("%d\n",n-2);int sm=0;
		fo(i,1,n)if(i!=res&&i!=mp[tmp^val[res]])printf("%d ",i);
		return 0;
	}
	mp.erase(val[n--]);res=ck2(n);
	printf("%d\n",n-2);//mp.erase(val[n]);
	fo(i,1,n)if(i!=res&&i!=mp[tmp^val[res]])printf("%d ",i);
	return 0;
}

T3 食材

这个不可改,根本看不懂题解诶......

标签:ch,return,17,rs,省选,sum,tr,int,模拟
来源: https://www.cnblogs.com/hzoi-fengwu/p/15906253.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有