省选模拟45

A. 虚数之树

存下点分树的结构

直接用线段树在上面修改就行

Code
#include<bits/stdc++.h>
#define int long long
#define inf 0x3f3f3f3f
#define meow(args...) fprintf(stderr,args)
using namespace std;
inline int read(){
	int x=0,f=1;char ch=getchar();
	while(ch<'0'||ch>'9'){if(ch=='-') f=-1;ch=getchar();}
	while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+(ch^48);ch=getchar();}
	return x*f;
}
int n,m,typ,S,rt,lans;
int siz[100010],mx[100010];
bool vis[100010];
vector<int>g[100010];
vector<pair<int,int>>vec[100010];
namespace SEG{
	#define lson st[x].ls
	#define rson st[x].rs
	int rt[100010],tot;
	struct seg{int ls,rs,mn;}st[100010*400];
	inline void pushup(int x){
		st[x].mn=inf;
		if(lson) st[x].mn=min(st[x].mn,st[lson].mn);
		if(rson) st[x].mn=min(st[x].mn,st[rson].mn);
	}
	void upd(int &x,int l,int r,int pos,int k){
		if(!x) x=++tot;if(l==r) return st[x].mn=k,void();
		int mid=(l+r)>>1;
		if(pos<=mid) upd(lson,l,mid,pos,k);
		else upd(rson,mid+1,r,pos,k);
		pushup(x);
	}
	int query(int x,int l,int r,int L,int R){
		if(!x) return inf;if(L<=l&&r<=R) return st[x].mn;
		int mid=(l+r)>>1,res=inf;
		if(L<=mid) res=min(res,query(lson,l,mid,L,R));
		if(R>mid) res=min(res,query(rson,mid+1,r,L,R));
		return res;
	}
	void print(int x,int l,int r){
		if(!x) return ;
		printf("l : %lld r : %lld mn : %lld\n",l,r,st[x].mn);
		if(l==r) return ;
		int mid=(l+r)>>1;
		print(lson,l,mid);
		print(rson,mid+1,r);
	}
	#undef lson
	#undef rson
}
void getrt(int x,int fa){
	siz[x]=1,mx[x]=0;
	for(auto y:g[x]) if(y!=fa&&!vis[y]){
		getrt(y,x);siz[x]+=siz[y];
		mx[x]=max(mx[x],siz[y]);
	}
	mx[x]=max(mx[x],S-siz[x]);
	if(mx[x]<mx[rt]) rt=x;
}
void dfs(int x,int fa,int dep){
	vec[x].emplace_back(make_pair(rt,dep));
	for(auto y:g[x]) if(y!=fa&&!vis[y]) dfs(y,x,dep+1);
}
void solve(int x){
	vis[x]=1;dfs(x,0,0);
	for(auto y:g[x]) if(!vis[y]){
		mx[rt=0]=inf;S=siz[y];getrt(y,0);
		mx[rt=0]=inf;S=siz[y];getrt(y,0);
		solve(rt);
	}
}
inline void ins(int x){for(auto L:vec[x]) SEG::upd(SEG::rt[L.first],1,n,x,L.second);}
inline void del(int x){for(auto L:vec[x]) SEG::upd(SEG::rt[L.first],1,n,x,inf);}
inline int query(int x,int l,int r){
	int mn=inf;
	for(auto L:vec[x]) mn=min(mn,SEG::query(SEG::rt[L.first],1,n,l,r)+L.second);
	return mn;
}
signed main(){
#ifdef LOCAL
	freopen("in","r",stdin);
	freopen("out","w",stdout);
#endif
	freopen("regression.in","r",stdin);
	freopen("regression.out","w",stdout);
	n=read();m=read();read();typ=read();
	for(int i=1,x,y;i<n;i++){
		x=read(),y=read();
		g[x].emplace_back(y);
		g[y].emplace_back(x);
	}
	S=n,mx[rt=0]=inf;getrt(1,0);solve(rt);
	for(int i=1,opt,x,l,r,v;i<=m;i++){
		opt=read();
		if(opt==1){x=read()^(lans*typ);ins(x);}
		if(opt==2){x=read()^(lans*typ);del(x);}
		if(opt==3){
			l=read();r=read();x=read()^(lans*typ);
			v=query(x,l,r);
			if(v<=n) printf("%lld\n",lans=v);else printf("-1\n");
		}
	}
	return 0;
}

B. 速通

前几天原题,注意转移细节

Code
#include<bits/stdc++.h>
#define int long long
#define rint signed
#define inf 0x3f3f3f3f3f3f3f3f
using namespace std;
inline int read(){
	int x=0,f=1;char ch=getchar();
	while(ch<'0'||ch>'9'){if(ch=='-') f=-1;ch=getchar();}
	while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+(ch^48);ch=getchar();}
	return x*f;
}
int n,lim;
int fa[110],L[110],R[110];
double f[110][1010],p[110],ans=1e10,sum,T;
vector<int>g[110];
void dfs(int x){
	for(auto y:g[x]) dfs(y);
	for(int i=0;i<=lim;i++){
		double div=1.0/(R[x]-L[x]+1),tmp=0;
		for(int j=L[x];j<=R[x];j++){
			if(i+j>lim){f[x][i]+=(T+j);continue;}
			if(g[x].empty()){f[x][i]+=j;continue;}
			sum=0;for(auto y:g[x]) sum+=f[y][i+j]*p[y];
			tmp=sum+j;tmp=min(tmp,(double)T+j);
			f[x][i]+=tmp;
		}
		f[x][i]*=div;
	}
}
inline bool check(double mid){
	memset(f,0,sizeof(f));
	T=mid;dfs(1);
	return f[1][0]<=mid;
}
signed main(){
#ifdef LOCAL
	freopen("in","r",stdin);
	freopen("out","w",stdout);
#endif
	freopen("isaac.in","r",stdin);
	freopen("isaac.out","w",stdout);
	ios::sync_with_stdio(false);cin.tie(0);
	cin>>n>>lim;
	for(int i=1;i<=n;i++) cin>>L[i]>>R[i];
	for(int i=2;i<=n;i++){
		cin>>fa[i]>>p[i];
		g[fa[i]].emplace_back(i);
	}
	double l=0,r=1000000000;
	while(r-l>1e-8){
		double mid=(l+r)/2.0;
		if(check(mid)) r=mid,ans=mid;
		else l=mid;
	}
	if(ans>1e9) puts("Remake");else printf("%.8lf\n",ans);
	return 0;
}

C. 叮叮车

发现 \(f(i)\) 其实就是卡特兰数

再乘上一个 \((i+1)\) 就变成了 \(\frac{2n!}{n!\times n!}\)

根据库默尔定理,答案就是在 \(7\) 进制下进位的次数

于是每一位的数越大越好

贴着上界走,将这一位减 \(1\) 再把后边都填成 \(6\)

也可以数位 \(dp\)

Code
#include<bits/stdc++.h>
#define int long long
#define inf 0x3f3f3f3f3f3f3f3f
#define meow(args...) fprintf(stderr,args)
using namespace std;
inline int read(){
	int x=0,f=1;char ch=getchar();
	while(ch<'0'||ch>'9'){if(ch=='-') f=-1;ch=getchar();}
	while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+(ch^48);ch=getchar();}
	return x*f;
}
int ll,rr,L,ans,v;
int a[100010],b[100010];
int A[100010],B[100010],C[100010];
char l[100010],r[100010];
inline int calc(){
	int res=0;
	for(int i=1;i<=rr;i++) C[i]*=2;
	for(int i=1;i<=rr;i++) if(C[i]>=7){
		res+=C[i]/7;C[i+1]+=C[i]/7;C[i]%=7;
		if(i==rr) rr++;
	}
	return res;
}
signed main(){
#ifdef LOCAL
	freopen("in","r",stdin);
	freopen("out","w",stdout);
#endif
	freopen("dingdingcar.in","r",stdin);
	freopen("dingdingcar.out","w",stdout);
	scanf("%s",l+1);ll=strlen(l+1);reverse(l+1,l+1+ll);
	scanf("%s",r+1);rr=strlen(r+1);reverse(r+1,r+1+rr);
	for(int i=1;i<=ll;i++) a[i]=l[i]-'0';a[0]=1;
	for(int i=1;i<=rr;i++) b[i]=r[i]-'0';b[0]=1;
	for(int i=1,now=0;ll;i++){
		for(int j=ll;j;j--){
			now=now*10+a[j];a[j]=now/7;now%=7;
			if(j==ll&&a[j]==0) ll--;
		}
		A[++A[0]]=now;now=0;
	}
	for(int i=1,now=0;rr;i++){
		for(int j=rr;j;j--){
			now=now*10+b[j];b[j]=now/7;now%=7;
			if(j==rr&&b[j]==0) rr--;
		}
		B[++B[0]]=now;now=0;
	}
	rr=B[0];
	for(int i=rr;i;i--) if(B[i]!=A[i]){L=i;break;}
	for(int K=L;~K;K--){
		memset(C,0,sizeof(C));
		for(int i=rr;i>K;i--) C[i]=B[i];C[K]=B[K]-1;for(int i=K-1;i>0;i--) C[i]=6;
		ans=max(ans,calc());
	}
	printf("%lld\n",ans);
	return 0;
}
posted @ 2022-04-05 15:19  Max_QAQ  阅读(66)  评论(0编辑  收藏  举报