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
首先判断一下,如果
剩下的二分答案。对于一个答案
点击查看代码
#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
首先明确一下题意,他说高桥没输过,代表他赢了或平了,在他每次都和前一次出的不一样的情况下,找到赢了的最大数。
考虑
考虑转移。每一个状态都可以从
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
这时一个比较有意思的题目。
首先明确一个概念,这个题可以一位一位做
设有三个数
, , 。
要算第个和第 个的异或值与第 个和第 个的异或值的和。那么如果按位算就是
前几步很好理解,最后一步呢?按位异或,按位,所以每一位每一位算就是。
那么考虑每一位(都是
先考虑一个问题,如果一些
那么对于一位(上文的每一位)中的所有区间(
这时我们发现,我们并不关心
我们把每一个数的当前位取出来,并算出前
点击查看代码
#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
线段树的奇妙用法。
我们考虑一种走法,我们一直往右走,直到右边是墙了,再往上/下走。可以想象一下正确性(类似贪心的感觉)。
那么我们走的时候有两种情况,一种是贯穿,就是一直走,不拐弯;另一种就是被迫走,就是被迫拐弯了(当然拐弯的时候也要能向右就向右),注意看下图,我们可以发现,被迫走一定是贴着边线在走。
那么我们可以用三元组
那么一段区间指的什么呢?指的是某些列,比如样例有图的那个,
点击查看代码
#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;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!