ABC365

A

link

题目已经说的很明白了,判断即可。

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

using namespace std;

int y;

signed main(){
	
	cin >> y;
	if(y%4 != 0) cout << 365;
	else if(y%4 == 0&&y%100 != 0) cout << 366;
	else if(y%100 == 0&&y%400 != 0) cout << 365;
	else if(y%400 == 0) cout << 366;
	
	return 0;
	
} 

B

link

emmm,排序找哪个位置是第二大。

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

using namespace std;

int a[105],b[105];

signed main(){
	
	int n;
	cin >> n;
	for(int i = 1;i <= n;++ i)
		cin >> a[i],b[i] = a[i];
	sort(a+1,a+1+n);
	
	for(int i = 1;i <= n;++ i)
		if(b[i] == a[n-1]) cout << i;
	
	return 0;
	
}

C

link

首先判断一下,如果Ai的总和还不到m,补贴就可以无限大,因为和Aimin,最后不会超过Ai的和。
剩下的二分答案。对于一个答案x,算出所需付的补贴金额,判断是否>m,如果在m范围内,可以让x变大,否则就要变小。

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

#define int long long

using namespace std;

int n,m;
int a[200005];
int sum;

int check(int x){
	int res = 0;
	for(int i = 1;i <= n;++ i)
		res += min(x,a[i]);
	return res;
}

signed main(){
	
	cin >> n >> m;
	for(int i = 1;i <= n;++ i)
		cin >> a[i],sum += a[i];
	
	if(sum <= m){
		cout << "infinite";
		return 0;
	}
	
	int l = 0,r = sum,md;
	
	while(l<r){
		md = (l+r+1)/2;
		int t = check(md);
		if(t > m) r = md-1;
		else l = md;
	}
	cout << l;
	
	return 0;
	
}

D

link

首先明确一下题意,他说高桥没输过,代表他赢了或平了,在他每次都和前一次出的不一样的情况下,找到赢了的最大数。
考虑DP,设fi,0/1fi,1代表到第i局中第i局赢了的赢的最大局数,fi,0代表到第i局中第i局平了的赢的最大局数。
考虑转移。每一个状态都可以从i1的所有状态(0/1)转移过来,只要判断这个状态高桥该出什么和前一个的哪一个状态高桥该出什么不一样即可。

if(这一个赢的状态!=上一个赢/平的状态)
  f[i][1] = max(f[i][1],f[i-1][1/0]+1);

大概这样即可。

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

using namespace std;

int n;
char s[200005];
char t[200005][2];
int f[200005][2];

char ying(char x){
	if(x == 'R') return 'P';
	else if(x == 'P') return 'S';
	else return 'R';
}

signed main(){
	
	cin >> n >> s+1;
	
	for(int i = 1;i <= n;++ i){
		t[i][1] = ying(s[i]);
		t[i][0] = s[i];
	}
	
	int ans = 0,q = 0;
	for(int i = 1;i <= n;++ i){
		if(t[i-1][0] != t[i][1])
			f[i][1] = max(f[i][1],f[i-1][0]+1);
		if(t[i-1][1] != t[i][0])
			f[i][0] = max(f[i][0],f[i-1][1]);
		if(t[i-1][0] != t[i][0])
			f[i][0] = max(f[i][0],f[i-1][0]);
		if(t[i-1][1] != t[i][1])
			f[i][1] = max(f[i][1],f[i-1][1]+1); 
	}
	
	cout << max(f[n][1],f[n][0]);
	
	return 0;
	
} 

E

link

这时一个比较有意思的题目。
首先明确一个概念,这个题可以一位一位做i=1N1j=i+1N(AiAi+1Aj),最后再放到那一位上(左移几个),把每一位加起来。证明一下。

设有三个数x1+x2<<1+x3<<2y1+y2<<1+y3<<2z1+z2<<1+z3<<2
要算第1个和第2个的异或值与第2个和第3个的异或值的和。那么如果按位算就是
(x1y1+y1z1)+(x2y2+y2z2)<<1+(x3y3+y3z3)<<2
=x1y1+y1z1+x2y2<<1+y2z2<<1+x3y3<<2+y3z3<<2
=(x1y1+x2y2<<1+x3y3<<2)+(y1z1+y2z2<<1+y3z3<<2)
=(x1+x2<<1+x3<<2)(y1+y2<<1+y3<<2)+(y1+y2<<1+y3<<2)(z1+z2<<1+z3<<2)
前几步很好理解,最后一步呢?按位异或,按位,所以每一位每一位算就是。

那么考虑每一位(都是01)的答案。
先考虑一个问题,如果一些01,如果有奇数个1,最后的结果就是1,如果有偶数个1,最后结果就是0。因为两个相同的1异或起来是0,奇数还有一个配不上对,剩一个1,而偶数就不剩了。
那么对于一位(上文的每一位)中的所有区间(1 ~ 21 ~ 31 ~ n2 ~ 32 ~ 42 ~ n……n1 ~ n),如果有奇数个1异或起来就是1,加到这一位的答案中就有效,否则无效。
这时我们发现,我们并不关心1的个数,只关心1的个数的奇偶性。
我们把每一个数的当前位取出来,并算出前i位中1的个数的奇偶性,为si。那么我们考虑什么情况一个区间l+1r1的个数有奇数个,如果前r位有奇数个1,那么前l位就得有偶数个1;如果前r位偶数个,那么前l位就有奇数个,那么前r位有sr个,前l位就得有sr1个。这样的区间是有效的,那么我们就要找有效的区间个数。所以对于一个结尾i,就要找i1之前的jsj=si1的个数。为什么是i1?刚刚有个小细节区间l+1r,且我们要让l+1<r(因为题目说最少加2个的异或值,不加一个的),所以l<r1,所以是i1之前的。那么怎么找呢?用两个cnt(可以开数组),分别记录前面为奇数和为偶数的个数,在每次的i前的jsj=si1(两个cnt中代表si1的奇偶性)的个数中加入答案后,把si1的奇偶性计入,因为在i时要算<i1的。

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

#define int long long

using namespace std;

int n;
int a[200005];
int cnt[2];
int s[200005];

int calc(int x){
	for(int i = 1;i <= n;++ i) s[i] = (a[i]>>x)&1;
	for(int i = 1;i <= n;++ i) s[i] ^= s[i-1];
	cnt[0] = cnt[1] = 0;
	int ans = 0;
	for(int i = 1;i <= n;++ i)
		ans += cnt[s[i]^1],cnt[s[i-1]]++;
	return ans;
}

signed main(){
	
	cin >> n;
	for(int i = 1;i <= n;++ i)
		cin >> a[i];
	
	int ans = 0;
	for(int i = 0;i <= 30;++ i){
		ans += calc(i)<<i;
	}
	
	cout << ans;
	
	return 0;
	
}

F

link

线段树的奇妙用法。
我们考虑一种走法,我们一直往右走,直到右边是墙了,再往上/下走。可以想象一下正确性(类似贪心的感觉)。
那么我们走的时候有两种情况,一种是贯穿,就是一直走,不拐弯;另一种就是被迫走,就是被迫拐弯了(当然拐弯的时候也要能向右就向右),注意看下图,我们可以发现,被迫走一定是贴着边线在走。

那么我们可以用三元组l,r,c来分别表示两种情况:贯穿时,lr指的是一段区间l~r这个范围内可以一直贯穿,不用拐弯,c=1,代表这个是贯穿;被迫走时,lr指的是从l进入,从r出去,c指的是竖着走的数量(注意不是rl,因为如果拐了好几拐,那么每个拐竖着走的都需要加上)。
那么一段区间指的什么呢?指的是某些,比如样例有图的那个,1 ~ 2列就是用一个3,3,1的三元组来表示;2 ~ 4列就是用一个3,5,2的三元组来表示(这里我们把纵坐标改一下,改成从上到下1~什么什么)。

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

#define int long long

using namespace std;

int n;
int a[200005],b[200005];
struct nd{
	int l,r,c;
}tr[800005]; 

nd pushup(nd x,nd y){
	nd ans;
	if(x.c == -1){
		if(y.c == -1){//贯穿  贯穿 
			if(max(x.l,y.l) <= min(x.r,y.r))
				ans = {max(x.l,y.l),min(x.r,y.r),-1};
			else if(x.l > y.r)
				ans = {x.l,y.r,x.l-y.r};
			else if(x.r < y.l)
				ans = {x.r,y.l,y.l-x.r};
		}
		else{//贯穿  被迫走
			if(x.l <= y.l&&y.l <= x.r)
				ans = y;
			else if(x.l > y.l)
				ans = {x.l,y.r,y.c+x.l-y.l};
			else if(x.r < y.l)
				ans = {x.r,y.r,y.c+y.l-x.r};
		}
	}
	else{
		if(y.c == -1){//被迫走  贯穿 
			if(y.l <= x.r&&x.r <= y.r)
				ans = x;
			else if(x.r < y.l)
				ans = {x.l,y.l,x.c+y.l-x.r};
			else if(x.r > y.r)
				ans = {x.l,y.r,x.c+x.r-y.r};
		}
		else{//被迫走  被迫走 
			ans = {x.l,y.r,x.c+y.c+abs(y.l-x.r)};
		}
	}
	return ans;
}

void build(int x,int l,int r){
	if(l == r){
		tr[x] = {a[l],b[l],-1};
		return;
	}
	int mid = (l+r)/2;
	build(x*2,l,mid);build(x*2+1,mid+1,r);
	tr[x] = pushup(tr[x*2],tr[x*2+1]);
}

nd query(int x,int l,int r,int xl,int xr){
	if(xl <= l&&r <= xr) return tr[x];
	int mid = (l+r)/2;
	if(xr <= mid) return query(x*2,l,mid,xl,xr);
	if(xl > mid) return query(x*2+1,mid+1,r,xl,xr);
	return pushup(query(x*2,l,mid,xl,xr),
		query(x*2+1,mid+1,r,xl,xr));
}

signed main(){
	
	cin >> n;
	for(int i = 1;i <= n;++ i)
		cin >> a[i] >> b[i];
	build(1,1,n);
	/*for(int i = 1;i <= 20;++ i){
		cout << i << " ";
		cout << tr[i].l << " " << tr[i].r << " ";
		cout << tr[i].c << endl;
	}*/
	int q;
	cin >> q;
	while(q--){
		int sx,sy,tx,ty;
		cin >> sx >> sy >> tx >> ty;
		if(sx > tx) swap(sx,tx),swap(sy,ty);
		if(sx == tx){
			cout << abs(sy-ty) << endl;
			continue;
		}
		nd a = query(1,1,n,sx,tx);
		a = pushup({sy,sy,-1},a);
		a = pushup(a,{ty,ty,-1});
		cout << a.c+tx-sx << endl;
	}
	
	return 0;
	
} 
posted @   不认命,就是哪吒的命!  阅读(53)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!
点击右上角即可分享
微信分享提示