首页 > 其他分享 >ABC 339 破防记

ABC 339 破防记

时间:2024-02-03 22:00:46浏览次数:33  
标签:ABC 339 int ll 破防 cin long using const

我是沙波。嘿!

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;
}

标签:ABC,339,int,ll,破防,cin,long,using,const
From: https://www.cnblogs.com/SFlyer/p/18005279

相关文章

  • ABC339 题解(A~G)
    A从后向前找到第一个.就行了。B按照题意模拟,设当前位置\(x,y\)移动方向\(dx,dy\)。那么下一步为\((x+dx,y+dy)\)设新的移动方向为\(dx',dy'\)如果顺时针旋转,则有\(dy'\gets-dx,dx'\getsdy\);如果逆时针,则有\(dx'\gets-dy,dy'\getsdx\)。C鉴定为除A以外......
  • [ABC279G] At Most 2 Colors 题解
    题目链接题目大意有一个\(1\timesN\)的格子和\(c\)种颜色,每个格子可以染上\(c\)种颜色中的一种。求任意相邻\(k\)个格子染色种类不超过\(2\)种的方案数。思路很明显,这是一个计数DP的题设\(f_i\)表示前\(i\)个格子染色的方案数,考虑第\(i\)个格子的染色情......
  • [ABC328G] Cut and Reorder 题解
    [ABC328G]CutandReorder题解状压fw实锤思路观察到排列操作只会做一次,答案的编号一定是一段一段的。所以可以考虑\(f_s\)表示前\(popcount(s)+1\)个\(a\)元素,放进\(b\)中\(s\)的最小代价转移可以考虑放置一段,每放一段需要\(c\)的代价。专业看起来复杂度非......
  • ABC338 A~D讲题
    A\(\text{Link}\)给你一个长度为\(n\)的字符串\(s\),判断\(s\)是否满足以下条件:\(s\)的第一个字符是大写字母,其余字符都是小写字母。代码:#include<bits/stdc++.h>usingnamespacestd;constintMAXN=1e5+5;chars[105];intmain(){ scanf("%s",s+1)......
  • AtCoder Beginner Contest 330 ABCDE
    AtCoderBeginnerContest330ABCDEA-CountingPasses签到题,不多说。//AConemoretimes//nndbk#include<bits/stdc++.h>usingnamespacestd;typedeflonglongll;constintmod=1e9+7;constintN=2e5+10;intmain(){ios::sync_with_stdi......
  • AT_abc243_g [ABC243G] Sqrt 题解
    可设\(f_i\)为以\(i\)开头的方案数,由于最后由于操作数很多所以不用考虑还剩多少次操作,显然可得状态转移方程\(f_i=\sum\limits_{j=1}^{\sqrti}f_j\),时间复杂度\(O(T+X\sqrtX)\),空间复杂度\(O(X)\),无法接受。考虑如何更优,可以发现在\(T\)次询问中,每次可以直接转移,因此......
  • 洛谷题单指南-暴力枚举-P3392 涂国旗
    原题链接:https://www.luogu.com.cn/problem/P3392题意解读:此题枚举白、蓝、红所有可能的行数组合,依次逐行判断每个方格,是否需要染色,计算最少的染色次数即可。解题思路:总行数是n,先考虑白色,第一行必是白色,最后一行必是红色,至少有一行蓝色,因此白色行数的范围是1~n-2再考虑蓝......
  • ABC334G Christmas Color Grid 2
    第一次AKabc,写篇题解记录一下。原题传送门分析发现实际上是要求删去每个绿点之后会多出几个连通块。发现这跟割点的定义很像,于是考虑建图,在相邻的绿点之间连边。然后就只要知道每个点到底被包含在几个点双里。我们使用圆方树,此时就只需要统计每个点的度数就可以了。代码#in......
  • ABC334F Christmas Present
    非常好dp,使我线段树旋转。原题传送门分析首先由于两点之间直线线段最短,我们肯定是希望从头一直送到尾,最后回家。但是有了\(k\)的限制,就麻烦了。考虑一个dp。我们设\(dp[i]\)表示刚送完第\(i\)个孩子时所要跑的最短距离。转移的时候我们枚举上一次回家是在送完哪一个孩......
  • ABC306F Merge Sets
    原题链接分析观察要求的式子:\(\sum_{1\leqi\ltj\leqN}f(S_i,S_j)\),发现可以拆成每一个集合\(S_i\)的贡献的和。那么我们考虑每一个集合\(S_i\)的贡献。显然,对于每一个\(S_i\),其贡献就是\(\sum_{i\ltj\leqN}f(S_i,S_j)\),也就是它与其后每一个集合\(S_j\)的......