ABC 339 破防记

我是沙波。嘿!

开局好的号打烂

A

好难。

Code
#include <bits/stdc++.h>

using namespace std;

using ll = long long;

int main(){
	ios::sync_with_stdio(false);
	cin.tie(0);

	string s;
	cin>>s;
	string t=s;
	reverse(t.begin(),t.end());
	string x;
	for (int i=0; i<t.size(); i++){
		if (t[i]=='.') break;
		x.push_back(t[i]);
	}
	reverse(x.begin(),x.end());
	cout<<x<<endl;
	return 0;
}
]

B

好难。英语太差了。

Code
#include <bits/stdc++.h>

using namespace std;

using ll = long long;

const int dx[] = {1,0,-1,0};
const int dy[] = {0,-1,0,1};

const int N = 1e2+2;

int n,m,x;
int d[N][N];

void gt(int &a,int b){
	if (a<=0){
		a+=b;
	}
	else{
		if (a>b){
			a=1;
		}
	}
}

int main(){
	ios::sync_with_stdio(false);
	cin.tie(0);

	cin>>n>>m>>x;
	int dir=2,cx=1,cy=1;
	for (int i=1; i<=x; i++){
		if (d[cx][cy]==1){
			d[cx][cy]=0;
			dir=(dir-1+4)%4;
			cx+=dx[dir],cy+=dy[dir];
			gt(cx,n),gt(cy,m);
		}
		else{
			d[cx][cy]=1;
			dir=(dir+1)%4;
			cx+=dx[dir],cy+=dy[dir];
			gt(cx,n),gt(cy,m);
		}
	}
	for (int i=1; i<=n; i++){
		for (int j=1; j<=m; j++){
			if (d[i][j]==0) cout<<".";
			else cout<<"#";
		}
		cout<<endl;
	}
	return 0;
}

C

比 A 简单。

点击查看代码
#include <bits/stdc++.h>

using namespace std;

using ll = long long;

const int N = 2e5+5;

ll n,a[N];

int main(){
	ios::sync_with_stdio(false);
	cin.tie(0);

	cin>>n;
	ll mn=0,cur=0;
	for (int i=1; i<=n; i++){
		cin>>a[i];
		cur+=a[i];
		mn=min(mn,cur);
	}
	cout<<cur-mn<<"\n";
	return 0;
}

D

\(dp_{a,b,c,d}\) 为两人在 \((a,b),(c,d)\) 的地方最小步数。bfs 即可。

Code
#include <bits/stdc++.h>

using namespace std;

using ll = long long;

const int N = 66;
const int dx[] = {0,0,-1,1};
const int dy[] = {1,-1,0,0};

struct node {
	int a,b,c,d;
};

int n;
string s[N];
int dp[N][N][N][N];

bool Bad(int x,int y){
	return x<=0 || y<=0 || x>n || y>n || s[x][y]=='#';
}

int main(){
	ios::sync_with_stdio(false);
	cin.tie(0);

	memset(dp,-1,sizeof dp);
	cin>>n;
	int sx1=-1,sy1=-1,sx2=-1,sy2=-1;
	for (int i=1; i<=n; i++){
		cin>>s[i];
		s[i]=" "+s[i];
		for (int j=1; j<=n; j++){
			if (s[i][j]=='P'){
				if (sx1==-1){
					sx1=i,sy1=j;
				}
				else{
					sx2=i,sy2=j;
				}
			}
		}
	}
	queue<node> q;
	q.push({sx1,sy1,sx2,sy2});
	memset(dp,-1,sizeof dp);
	dp[sx1][sy1][sx2][sy2]=0;
	while (!q.empty()){
		auto u=q.front();
		q.pop();
		int a=u.a,b=u.b,c=u.c,d=u.d;
		for (int i=0; i<4; i++){
			int na=a+dx[i],nb=b+dy[i];
			int nc=c+dx[i],nd=d+dy[i];
			if (Bad(na,nb)){
				na=a,nb=b;
			}
			if (Bad(nc,nd)){
				nc=c,nd=d;
			}
			if (dp[na][nb][nc][nd]==-1){
				dp[na][nb][nc][nd]=dp[a][b][c][d]+1;
				q.push({na,nb,nc,nd});
			}
		}
	}
	int mn=2e9;
	for (int a=1; a<=n; a++){
		for (int b=1; b<=n; b++){
			if (dp[a][b][a][b]!=-1){
				mn=min(mn,dp[a][b][a][b]);
			}
		}
	}
	if (mn==2e9){
		cout<<-1<<endl;
	}
	else{
		cout<<mn<<endl;
	}
	return 0;
}

E

\(dp_i\) 为结尾为 \(i\) 的最大长度。\(dp_{i}=\max_{j=1}^{i-1} dp_j\times [|a_j-a_i|\le d]+1\)。这个可以线段树优化。

没有线段树开 \(4\) 倍空间挂了。

Code
#include <bits/stdc++.h>

using namespace std;

using ll = long long;

const int N = 5e5+5;

ll n,a[N],d,dp[N],ans;
ll mx[N<<2];

void upd(int k,int l,int r,int x,ll vl){
	if (l==r){
		mx[k]=max(mx[k],vl);
		return;
	}
	int mid=l+r>>1;
	if (x<=mid){
		upd(k<<1,l,mid,x,vl);
	}
	else{
		upd(k<<1|1,mid+1,r,x,vl);
	}
	mx[k]=max(mx[k<<1],mx[k<<1|1]);
}

ll qy(int k,int l,int r,int ql,int qr){
	if (l>qr || r<ql){
		return 0;
	}
	if (ql<=l && r<=qr){
		return mx[k];
	}
	int mid=l+r>>1;
	ll vl=qy(k<<1,l,mid,ql,qr);
	ll vr=qy(k<<1|1,mid+1,r,ql,qr);
	return max(vl,vr);
}

int main(){
	ios::sync_with_stdio(false);
	cin.tie(0);
	
	cin>>n>>d;
	for (int i=1; i<=n; i++){
		cin>>a[i];
	}
	for (int i=1; i<=n; i++){
		dp[i]=qy(1,1,N-1,max(1ll,a[i]-d),min(N-1ll,a[i]+d))+1;
		ans=max(ans,dp[i]);
		upd(1,1,N-1,a[i],dp[i]);
	}
	cout<<ans<<endl;
	return 0;
}

F

考虑如果给每一个数用一个大质数取模,然后判断时之间判断取模后乘起来想不想等。这样取 \(3\) 次不同的大质数就可以很高概率过。

\(ans\) 取模+强度不过挂了。

Code
#include <bits/stdc++.h>

using namespace std;

using ll = long long;

const int N = 1e3+3;
const ll mod1 = 998244853;
const ll mod2 = 1e9+9;
const ll mod3 = 1e9+7;

int n;
ll a[N],b[N],c[N];

int main(){
	ios::sync_with_stdio(false);
	cin.tie(0);

	cin>>n;
	map<pair<ll,pair<ll,ll> >,ll> mp;
	for (int i=1; i<=n; i++){
		a[i]=0;
		string s;
		cin>>s;
		for (auto ch : s){
			a[i]=(a[i]*10ll+ch-'0')%mod1;
			b[i]=(b[i]*10ll+ch-'0')%mod2;
			c[i]=(c[i]*10ll+ch-'0')%mod3;
		}
	}
	for (int i=1; i<=n; i++){
		mp[{a[i],{b[i],c[i]}}]++;
	}
	ll ans=0;
	for (int i=1; i<=n; i++){
		for (int j=1; j<=n; j++){
			ll x=a[i]*a[j]%mod1;
			ll y=b[i]*b[j]%mod2;
			ll z=c[i]*c[j]%mod3;
			ans+=mp[{x,{y,z}}];
		}
	}
	cout<<ans<<endl;
	return 0;
}

G

你不会可持久化线段树也可以,比如我。

找到模板题,第 \(k\) 小是什么,然后魔改。二分出 \(x\) 是第几小,然后就可以了。很蠢。

主席树 qy2 return 错了,挂了。

Code
#include <bits/stdc++.h>

using namespace std;

using ll = long long;

#define int long long

const int N = 2e5+5;

int n,q,m,cnt;
int a[N],b[N],t[N];
int sum[N<<5],ls[N<<5],rs[N<<5],val[N<<5];

int bd(int l,int r){
	int k=++cnt;
	sum[k]=0;
	int mid=l+r>>1;
	if (l<r){
		ls[k]=bd(l,mid);
		rs[k]=bd(mid+1,r);
	}
	return k;
}

int upd(int pr,int l,int r,int x,ll vl){
	int k=++cnt;
	ls[k]=ls[pr];
	rs[k]=rs[pr];
	sum[k]=sum[pr]+1;
	val[k]=val[pr]+vl; 
	int mid=l+r>>1;
	if (l<r){
		if (x<=mid){
			ls[k]=upd(ls[pr],l,mid,x,vl);
		}
		else{
			rs[k]=upd(rs[pr],mid+1,r,x,vl); 
		}
	}
	return k;
}

int qy(int u,int v,int l,int r,int k){
	if (l>=r){
		return l;
	}
	int x=sum[ls[v]]-sum[ls[u]];
	int mid=l+r>>1;
	if (x>=k){
		return qy(ls[u],ls[v],l,mid,k);
	}
	else{
		return qy(rs[u],rs[v],mid+1,r,k-x);
	}
}

int qy2(int u,int v,int l,int r,int k){
	if (l>=r){
		return val[v]-val[u];
	}
	int x=sum[ls[v]]-sum[ls[u]];
	int vl=val[ls[v]]-val[ls[u]];
	int mid=l+r>>1;
	if (x>=k){
		return qy2(ls[u],ls[v],l,mid,k);
	}
	else{
		return vl+qy2(rs[u],rs[v],mid+1,r,k-x);
	}
}

signed main(){
	ios::sync_with_stdio(false);
	cin.tie(0);

	cin>>n;
	for (int i=1; i<=n; i++){
		cin>>a[i];
		b[i]=a[i];
	}
	sort(b+1,b+1+n);
	m=unique(b+1,b+1+n)-b-1;
	t[0]=bd(1,m);
	for (int i=1; i<=n; i++){
		int pos=lower_bound(b+1,b+1+m,a[i])-b;
		t[i]=upd(t[i-1],1,m,pos,a[i]);
	}
	int lst=0;
	cin>>q;
	while (q--){
		int l,r,k;
		cin>>l>>r>>k;
		l^=lst,r^=lst,k^=lst;
		int lb=0,rb=r-l+2;
		while (lb+1<rb){
			int mid=lb+rb>>1;
			int res=qy(t[l-1],t[r],1,m,mid);
			if (b[res]>k){
				rb=mid;
			}
			else{
				lb=mid;
			}
		}
		int res=qy2(t[l-1],t[r],1,m,lb);
		if (lb==0){
			res=0;
		}
		cout<<res<<"\n";
		lst=res;
	}
	return 0;
}
posted @ 2024-02-03 21:54  SFlyer  阅读(59)  评论(0编辑  收藏  举报