21牛客多校第八场

A

签到题,注意\(x=0\)的特例,求逆元即可

#include<bits/stdc++.h>
#define inf 2139062143
#define ll long long
#define db double
#define ld long double
#define ull unsigned long long
#define MAXN 100100
#define MOD 4933
#define Fill(a,x) memset(a,x,sizeof(a))
#define rep(i,s,t) for(int i=(s),i##end=(t);i<=i##end;++i)
#define dwn(i,s,t) for(int i=(s),i##end=(t);i>=i##end;--i)
#define ren for(int i=fst[x];i;i=nxt[i])
#define pls(a,b) (a+b)%MOD
#define mns(a,b) (a-(b)+MOD)%MOD
#define mul(a,b) (1LL*(a)*(b))%MOD
#define pii pair<int,int>
#define fi first
#define se second
#define pb push_back
using namespace std;
inline int read()
{
    int x=0,f=1;char ch=getchar();
    while(!isdigit(ch)) {if(ch=='-') f=-1;ch=getchar();}
    while(isdigit(ch)) {x=x*10+ch-'0';ch=getchar();}
    return x*f;
}
int qp(int x,int t,int res=1)
{
	for(;t;t>>=1,x=mul(x,x)) if(t&1) res=mul(res,x);
	return res;
}
int n,m,k,a,l;
int main()
{
	n=read(),m=read(),k=read(),a=read(),l=read();
	int x,y,z,res=1;
	rep(i,1,k) {x=read(),y=read(),z=read();if(x) res=mul(res,qp(z,MOD-2,z-y));} 
	printf("%d\n",pls(res,a));
}

D

由于\(a+b=(a|b)+(a\&b)\),则每一位的限制是独立的,分别\(O(n)\)判断

#include<bits/stdc++.h>
#define inf 2139062143
#define ll long long
#define db double
#define ld long double
#define ull unsigned long long
#define MAXN 100100
#define MOD 998244353
#define Fill(a,x) memset(a,x,sizeof(a))
#define rep(i,s,t) for(int i=(s),i##end=(t);i<=i##end;++i)
#define dwn(i,s,t) for(int i=(s),i##end=(t);i>=i##end;--i)
#define ren for(int i=fst[x];i;i=nxt[i])
#define pls(a,b) (a+b)%MOD
#define mns(a,b) (a-(b)+MOD)%MOD
#define mul(a,b) (1LL*(a)*(b))%MOD
#define pii pair<int,int>
#define fi first
#define se second
#define pb push_back
using namespace std;
inline int read()
{
    int x=0,f=1;char ch=getchar();
    while(!isdigit(ch)) {if(ch=='-') f=-1;ch=getchar();}
    while(isdigit(ch)) {x=x*10+ch-'0';ch=getchar();}
    return x*f;
}
int n,b[MAXN],c[MAXN],ans=1;
inline int cheq(int x,int j)
{
	rep(i,2,n)
	{
		if((c[i]>>j)&1){if(!x) return 0;}
		else if((b[i]>>j)&1) x^=1;
		else {if(x) return 0;}
	}
	return 1;
}
int main()
{
	n=read();
	rep(i,2,n) b[i]=read();
	rep(i,2,n) {c[i]=read(),c[i]-=b[i];if(c[i]<0) return puts("0"),0;}
	dwn(j,29,0)
	{
		if((c[2]>>j)&1)
			{if(!cheq(1,j)) return puts("0"),0;}
		else if((b[2]>>j)&1)
		{
			int tmp=cheq(1,j)+cheq(0,j);
			if(!tmp) return puts("0"),0;
			else ans*=tmp;
		}
		else 
			{if(!cheq(0,j)) return puts("0"),0;}
	}
	printf("%d\n",ans);
}

E

签到题 \(puts("no")\)

#include<bits/stdc++.h>
#define inf 2139062143
#define ll long long
#define db double
#define ld long double
#define ull unsigned long long
#define MAXN 100100
#define MOD 998244353
#define Fill(a,x) memset(a,x,sizeof(a))
#define rep(i,s,t) for(int i=(s),i##end=(t);i<=i##end;++i)
#define dwn(i,s,t) for(int i=(s),i##end=(t);i>=i##end;--i)
#define ren for(int i=fst[x];i;i=nxt[i])
#define pls(a,b) (a+b)%MOD
#define mns(a,b) (a-(b)+MOD)%MOD
#define mul(a,b) (1LL*(a)*(b))%MOD
#define pii pair<int,int>
#define fi first
#define se second
#define pb push_back
using namespace std;
inline int read()
{
    int x=0,f=1;char ch=getchar();
    while(!isdigit(ch)) {if(ch=='-') f=-1;ch=getchar();}
    while(isdigit(ch)) {x=x*10+ch-'0';ch=getchar();}
    return x*f;
}
int main()
{
	rep(T,1,read()) 
	{
		puts("no");
	}
}

F

考虑按照列分治,每次分治处理出\(mid\)两侧的点分别能到达\(mid\)这一列的哪些点

\(bitset\)记录,这一部分复杂度为\(O(\frac{n^2mlogm}{w})\)

把所有询问挂到起点的位置,每次分治都可以计算出询问点的列在\([l,r]\)范围内且 起点与终点分别位于\(mid\)两侧的答案

注意终点列在\(mid\)时需要特殊处理

#include<bits/stdc++.h>
#define inf 2139062143
#define ll long long
#define db double
#define ld long double
#define ull unsigned long long
#define MAXN 500100
#define MOD 998244353
#define Fill(a,x) memset(a,x,sizeof(a))
#define rep(i,s,t) for(int i=(s),i##end=(t);i<=i##end;++i)
#define dwn(i,s,t) for(int i=(s),i##end=(t);i>=i##end;--i)
#define ren for(int i=fst[x];i;i=nxt[i])
#define pls(a,b) (a+b)%MOD
#define mns(a,b) (a-(b)+MOD)%MOD
#define mul(a,b) (1LL*(a)*(b))%MOD
#define pii pair<int,int>
#define fi first
#define se second
#define pb push_back
using namespace std;
inline int read()
{
    int x=0,f=1;char ch=getchar();
    while(!isdigit(ch)) {if(ch=='-') f=-1;ch=getchar();}
    while(isdigit(ch)) {x=x*10+ch-'0';ch=getchar();}
    return x*f;
}
int n,m,ans[MAXN],cur[550][550];
struct Ask{int x,y,id;}g;
bool operator < (Ask &a,Ask &b) {return a.y<b.y;}
char ch[550][550];
bitset<505> f[510][510];
vector<Ask> q[550][550];
void Div(int l,int r)
{
	int mid=l+r>>1;if(l<mid) Div(l,mid-1);if(mid<r) Div(mid+1,r);
	rep(i,1,n)
	{
		f[i][mid].reset();
		if(ch[i][mid]=='0')
		{
			f[i][mid][i]=1;
			if(i!=1) f[i][mid]|=f[i-1][mid];
		}
	}
	rep(j,mid+1,r) rep(i,1,n) if(ch[i][j]!='1')
	{
		if(i!=1) f[i][j]=f[i-1][j]|f[i][j-1];
		else f[i][j]=f[i][j-1];
	}
	dwn(i,n,1)
	{
		f[i][mid].reset();
		if(ch[i][mid]=='0')
		{
			f[i][mid][i]=1;
			if(i!=n) f[i][mid]|=f[i+1][mid];
		}
	}
	dwn(j,mid-1,l) dwn(i,n,1) if(ch[i][j]!='1')
	{
		if(i!=n) f[i][j]=f[i+1][j]|f[i][j+1];
		else f[i][j]=f[i][j+1];
	}
	rep(j,l,mid) rep(i,1,n) if(q[i][j].size())
		for(int &st=cur[i][j],ed=q[i][j].size()-1;st<=ed;st++)
		{
			g=q[i][j][st];if(g.y>r) break;
			if(g.y==mid) ans[g.id]=f[i][j][g.x];
			else ans[g.id]=(f[i][j]&f[g.x][g.y]).any();
		}
}
int main()
{
	n=read(),m=read();int Q,x,a,b,c,d;
	rep(i,1,n) scanf("%s",ch[i]+1);
	Q=read();rep(i,1,Q)
	{
		x=read(),a=read(),b=read(),c=read(),d=read();
		if(x==1) {if(b==d&&a<=c) q[a][b].pb({c,d,i});}
		else if(x==2) {if(a==c&&b<=d) q[a][b].pb({c,d,i});}
		else if(a<=c&&b<=d) q[a][b].pb({c,d,i});
	}
	rep(i,1,n) rep(j,1,m) if(q[i][j].size())
		sort(q[i][j].begin(),q[i][j].end());
	Div(1,m);rep(i,1,Q) puts(ans[i]?"yes":"no");
}

J

\(dp\)出不在\(s\rightarrow t\)链上的点离开的最长链,则题目转化为链上的博弈

例如对于\((x,y,0)\)这个状态,表示两人在\((x,y)\)位置,当前决策人是\(x\)

当前的决策人要么继续向前走一步,要么选择离开这条链,对手则可以在\((x+1,y)\)内选择一个最大值离开

容易发现维护一个\(RMQ\)之后状态只有\(O(n)\)个,直接\(dfs\)模拟即可,而这个\(RMQ\)可以在递归的过程中维护

#include<bits/stdc++.h>
#define inf 2139062143
#define ll long long
#define db double
#define ld long double
#define ull unsigned long long
#define MAXN 500100
#define MOD 998244353
#define Fill(a,x) memset(a,x,sizeof(a))
#define rep(i,s,t) for(int i=(s),i##end=(t);i<=i##end;++i)
#define dwn(i,s,t) for(int i=(s),i##end=(t);i>=i##end;--i)
#define ren for(int i=fst[x];i;i=nxt[i])
#define pls(a,b) (a+b)%MOD
#define mns(a,b) (a-(b)+MOD)%MOD
#define mul(a,b) (1LL*(a)*(b))%MOD
#define pii pair<int,int>
#define fi first
#define se second
#define pb push_back
using namespace std;
inline int read()
{
    int x=0,f=1;char ch=getchar();
    while(!isdigit(ch)) {if(ch=='-') f=-1;ch=getchar();}
    while(isdigit(ch)) {x=x*10+ch-'0';ch=getchar();}
    return x*f;
}
int n,nxt[MAXN<<1],fst[MAXN],to[MAXN<<1],cnt,dp[MAXN],in[MAXN],fa[MAXN];
int s,t,g[MAXN],tot,w1[MAXN],w2[MAXN],mx1,mx2;
void add(int u,int v) {nxt[++cnt]=fst[u],fst[u]=cnt,to[cnt]=v;}
void getf(int x,int pa)
{
	fa[x]=pa;ren if(to[i]^pa) getf(to[i],x);
}
void dfs(int x,int pa)
{
	ren if(to[i]^pa)
	{
		dfs(to[i],x);
		if(!in[to[i]]) dp[x]=max(dp[x],dp[to[i]]+1);
	}
}
int solve(int x,int y,int now)
{
	if(y==x+1)
	{
		mx1=max(w1[x],w1[y]),mx2=max(w2[x],w2[y]);
		return w1[x]-w2[y];
	}
	int res=now?solve(x,y-1,now^1):solve(x+1,y,now^1);
	if(!now) res=max(res,w1[x]-mx2),mx1=max(mx1,w1[x]),mx2=max(mx2,w2[x]);
	else res=min(res,mx1-w2[y]),mx1=max(mx1,w1[y]),mx2=max(mx2,w2[y]);
	return res;
}
int main()
{
	n=read(),s=read(),t=read();int a,b;
	rep(i,2,n) a=read(),b=read(),add(a,b),add(b,a);
	getf(s,0);for(a=t;a;a=fa[a]) {in[a]=1;g[++tot]=a;}
	dfs(s,0);n=tot;rep(i,1,n>>1) swap(g[i],g[n-i+1]);
	rep(i,1,n) w1[i]=i-1+dp[g[i]],w2[i]=n-i+dp[g[i]];
	printf("%d\n",solve(1,n,0));
}

K

对于一个直线要么沿着短边前进获得\(2\)的贡献,要么沿着对角线走获得\(3\)的贡献

不妨令\(a,b\)分别表示短边和对角线长度,则答案为\(max\{2x+3y+4\},xa+yb\le \pi;x,y\in N\)

显然\(x,y\)不能超过\(2\),否则根据\(3a\)\(2b\)的大小关系一定能得到更优的解

直接枚举这个较小数即可

#include<bits/stdc++.h>
#define inf 2139062143
#define ll long long
#define db double
#define ld long double
#define ull unsigned long long
#define MAXN 100100
#define MOD 998244353
#define Fill(a,x) memset(a,x,sizeof(a))
#define rep(i,s,t) for(int i=(s),i##end=(t);i<=i##end;++i)
#define dwn(i,s,t) for(int i=(s),i##end=(t);i>=i##end;--i)
#define ren for(int i=fst[x];i;i=nxt[i])
#define pls(a,b) (a+b)%MOD
#define mns(a,b) (a-(b)+MOD)%MOD
#define mul(a,b) (1LL*(a)*(b))%MOD
#define pii pair<int,int>
#define fi first
#define se second
#define pb push_back
using namespace std;
inline int read()
{
    int x=0,f=1;char ch=getchar();
    while(!isdigit(ch)) {if(ch=='-') f=-1;ch=getchar();}
    while(isdigit(ch)) {x=x*10+ch-'0';ch=getchar();}
    return x*f;
}
const db pi=acos(-1);
db a,b;int ans;
int main()
{
	rep(T,1,read())
	{
		cin>>a>>b;if(a>b) swap(a,b);
		b=sqrt(a*a+b*b);ans=0;
		rep(i,0,2)
		{
			if(i*b<pi) ans=max(ans,3*i+2*(int)((pi-i*b)/a));
			if(i*a<pi) ans=max(ans,2*i+3*(int)((pi-i*a)/b));
		}
		printf("%d\n",ans+4);
	}
}
posted @ 2021-08-10 16:12  jack_yyc  阅读(71)  评论(0编辑  收藏  举报