疯狂写,结果卡在t3的分类讨论当场暴毙,切完t4困得受不了睡觉去了。
难度:红
#include<bits/stdc++.h>
#define ll long long
#define mxn 100010
using namespace std;
ll t,n,k,ans,a[mxn],c;
void solve(){
cin>>n;
for(int i=1;i<=n;i++)cin>>a[i];
for(int i=2;i<=n;i++){
c=fabs(a[i]-a[i-1]);
if(c!=5&&c!=7){
cout<<"NO\n";return;
}
}
cout<<"YES\n";
return;
}
int main(){
ios::sync_with_stdio(0);
cin.tie(0),cout.tie(0);
cin>>t;while(t--)solve();
return 0;
}
难度:橙
排序一下就行了。
#include<bits/stdc++.h>
#define ll long long
#define mxn 200010
using namespace std;
ll t,n,k,ans,a[mxn],c;
void solve(){
cin>>n>>k;
ll d=0;
ans=0;
memset(a,0,sizeof(a));
for(int i=1;i<=k;i++){
ll b,c;cin>>b>>c;
a[b]+=c;d=max(d,b);
}
sort(a+1,a+d+1,[](ll x,ll y){
return x>y;
});
for(int i=1;i<=n;i++)
ans+=a[i];
cout<<ans<<'\n';
return;
}
int main(){
ios::sync_with_stdio(0);
cin.tie(0),cout.tie(0);
cin>>t;while(t--)solve();
return 0;
}
难度:橙-黄
分类讨论。
#include<bits/stdc++.h>
#define ll long long
#define mxn 200010
using namespace std;
ll len,q,pos[mxn],cnt;
char s[mxn];
void solve(){
cin>>s+1>>q;
memset(pos,0,sizeof(pos));
len=strlen(s+1),cnt=0;
for(int i=1;i<=len-3;i++)
if(s[i]=='1'&&s[i+1]=='1'&&s[i+2]=='0'&&s[i+3]=='0')
cnt++;
while(q--){
int v;char t;cin>>v>>t;
if(s[v]==t){
if(cnt)cout<<"YES\n";
else cout<<"NO\n";
continue;
}
if(s[v]=='0'){
if(v-3>=1&&s[v-3]=='1'&&s[v-2]=='1'&&s[v-1]=='0')cnt--;
else if(v-2>=1&&v+1<=len&&s[v-2]=='1'&&s[v-1]=='1'&&s[v+1]=='0')cnt--;
}
else{
if(v+3<=len&&s[v+1]=='1'&&s[v+2]=='0'&&s[v+3]=='0')cnt--;
else if(v-1>=1&&v+2<=len&&s[v-1]=='1'&&s[v+1]=='0'&&s[v+2]=='0')cnt--;
}
s[v]=t;
if(t=='0'){
if(v-3>=1&&s[v-3]=='1'&&s[v-2]=='1'&&s[v-1]=='0')cnt++;
else if(v-2>=1&&v+1<=len&&s[v-2]=='1'&&s[v-1]=='1'&&s[v+1]=='0')cnt++;
}
else{
if(v+3<=len&&s[v+1]=='1'&&s[v+2]=='0'&&s[v+3]=='0')cnt++;
else if(v-1>=1&&v+2<=len&&s[v-1]=='1'&&s[v+1]=='0'&&s[v+2]=='0')cnt++;
}
if(cnt)cout<<"YES\n";
else cout<<"NO\n";
}
return;
}
int main(){
ios::sync_with_stdio(0);
cin.tie(0),cout.tie(0);
int t;cin>>t;while(t--)solve();
return 0;
}
难度:橙-黄
计数时注意破环成链。
#include<bits/stdc++.h>
#define ll long long
#define mxn 1010
#define pb push_back
using namespace std;
ll n,m,ans;
char s[mxn][mxn];
vector<int> t;
void get(ll x,ll y){
t.clear();
for(int i=y;i<m-y+1;i++)t.pb(s[x][i]-'0');
for(int i=x;i<n-x+1;i++)t.pb(s[i][m-y+1]-'0');
for(int i=m-y+1;i>y;i--)t.pb(s[n-x+1][i]-'0');
for(int i=n-x+1;i>x;i--)t.pb(s[i][y]-'0');
ll tot=0;
for(int i=y;i<m-y+1&&tot<=2;i++)t.pb(s[x][i]-'0'),tot++;
for(int i=x;i<n-x+1&&tot<=2;i++)t.pb(s[i][m-y+1]-'0'),tot++;
for(int i=m-y+1;i>y&&tot<=2;i--)t.pb(s[n-x+1][i]-'0'),tot++;
for(int i=0;i+3<t.size();i++){
if(t[i]==1&&t[i+1]==5&&t[i+2]==4&&t[i+3]==3)
ans++;
}
}
void solve(){
cin>>n>>m;
ans=0;
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
cin>>s[i][j];
for(int i=1;i<=min(n,m)/2;i++)
get(i,i);
cout<<ans<<'\n';
}
int main(){
ios::sync_with_stdio(0);
cin.tie(0),cout.tie(0);
int t;cin>>t;while(t--)solve();
return 0;
}
难度:黄
注意到创建河道之后地区的值具有单调性,所以可以二分。本质上是一个线段交问题。
#include<bits/stdc++.h>
#define ll long long
#define mxn 100010
#define pb push_back
using namespace std;
ll n,m,q,k;
vector<int> t[mxn];
void solve(){
cin>>k;
int x=1,y=n,pos;
for(int i=1;i<=k;i++){
int a,l;char c;cin>>a>>c>>l;
if(c=='<')pos=lower_bound(t[a].begin(),t[a].end(),l)-t[a].begin(),y=min(y,pos);
else pos=upper_bound(t[a].begin(),t[a].end(),l)-t[a].begin()+1,x=max(x,pos);
}
if(x>y||y==0||x>n)cout<<"-1\n";
else cout<<x<<'\n';
}
int main(){
ios::sync_with_stdio(0);
cin.tie(0),cout.tie(0);
cin>>n>>m>>q;
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++){
int a;cin>>a;
t[j].pb(a);
if(i>1)t[j][i-1]|=t[j][i-2];
}
while(q--)solve();
return 0;
}
难度:黄-绿
我们应注意到这样一条性质:
\[0\oplus1\oplus...\oplus n
\left\{
\begin{array}{lcl}
x& &n\equiv0\ (mod\ 4)\\
1& &n\equiv1\ (mod\ 4)\\
x+1& &n\equiv2\ (mod\ 4)\\
0& &n\equiv3\ (mod\ 4)
\end{array}
\right.
\]
所以我们可以 \(O(1)\) 求出 \(l\oplus l+1\oplus...\oplus r\)。
然后,我们要把那些不有趣的数去掉。这里我们对低于 \(i\) 位和高于 \(i\) 位进行分类讨论。
#include<bits/stdc++.h>
#define ll long long
using namespace std;
ll get(ll n){
if(n<=0)return 0;
if(n%4==0)return n;
if(n%4==1)return 1;
if(n%4==2)return n+1;
if(n%4==3)return 0;
}
ll t,l,r,i,k,mod;
void solve(){
cin>>l>>r>>i>>k;
ll ans=get(r)^get(l-1),a,b;
mod=1<<i;
if(l%mod<=k)a=l/mod;
else a=l/mod+1;
if(r%mod>=k)b=r/mod;
else b=r/mod-1;
if(a<=b){
ans^=((get(b)^get(a-1))<<i);
ans^=k*((b-a+1)&1);
}
cout<<ans<<'\n';
}
int main(){
ios::sync_with_stdio(0);
cin.tie(0),cout.tie(0);
cin>>t;while(t--)solve();
return 0;
}
难度:绿-蓝
我们从 \(n\) 的最大位开始找三个数中的最大位,注意这里的位是在二进制下。
假设查询的为第 \(i\) 位。我们查询 xor 2^i min(2^(i+1)-1,n)
。若查询结果不为 \(0\),则说明这一位上有数字。
为什么呢?假设有一个或三个数有这一位,则查询的结果必不为 \(0\)。
若是两个数,因为这两个数不可能相同,所以也不可能是 \(1\)。
若第 \(i\) 位上有数字,则 \(ans\) 要加上 \(2^i\),之后查询的时候要把查询的两个数异或上 \(ans\)。这样就能确定每一位上是否有数了。
另外,我们要求的有 \(3\) 个数 \(a,b,c\)。在求 \(b\) 时,若 \(a\) 在询问的 \(l\sim r\) 范围内,就要把结果异或上 \(a\)。
求 \(c\) 时也是如此。
#include<bits/stdc++.h>
#define ll long long
using namespace std;
ll n,t,a,b,c,mxbit;
ll ask(ll l,ll r,ll id){
if(l>n)return 0;
r=min(r,n);
cout<<"xor "<<l<<' '<<r<<endl;
ll ret;cin>>ret;
if(id>1&&a>=l&&a<=r)ret^=a;
if(id>2&&b>=l&&b<=r)ret^=b;
return ret;
}
void solve(){
cin>>n;
a=b=c=0;
for(ll i=(1ll<<62),bit=62;i;i>>=1,bit--){
if(n&i){
mxbit=bit;
break;
}
}
for(ll i=(1ll<<mxbit);i;i>>=1)
if(ask(i|a,(i*2-1)|a,1))a|=i;
for(ll i=(1ll<<mxbit);i;i>>=1)
if(ask(i|b,(i*2-1)|b,2))b|=i;
c=ask(1,n,3);
cout<<"ans "<<a<<' '<<b<<' '<<c<<endl;
}
int main(){
ios::sync_with_stdio(0);
cin.tie(0),cout.tie(0);
cin>>t;while(t--)solve();
return 0;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 单线程的Redis速度为什么快?
· 展开说说关于C#中ORM框架的用法!
· Pantheons:用 TypeScript 打造主流大模型对话的一站式集成库
· SQL Server 2025 AI相关能力初探
· 为什么 退出登录 或 修改密码 无法使 token 失效