比赛链接
T1
50 pts。
直接暴力。
思路
我们可以发现,题目中的变化只是将字符串中的 A 挪到了最后,所以如果出现了 AABC 这种情况,才会发生连锁反应,因为是从后往前反应,所以枚举的时候从前往后,统计 A 的个数,如果遇到了 B,并且下一个是 C,答案就加上 A 的个数,如果是 C 的话,就将个数清零。
代码
#include<bits/stdc++.h>
#define int long long
using namespace std;
string s;
signed main()
{cin.tie(0)->sync_with_stdio(false);cin>>s;int ans=0,cnt=0;for(int i=0;i<s.size();++i){if(s[i]=='A') ++cnt;else if(s[i]=='B'){if(i+1<s.size()&&s[i+1]=='C'){ans+=cnt;++i;}else cnt=0;}else cnt=0;}cout<<ans;return 0;
}
T2
50 pts。
最短路暴力。
思路
记忆化搜索乘法的情况即可。
代码
#include<bits/stdc++.h>
#define int unsigned long long
using namespace std;
int n,a,b,c,d;
unordered_map<int,int> dp;
int dfs(int x)
{if(dp.count(x)) return dp[x];int mn=x*d;if(x%2==0) mn=min(mn,dfs(x/2)+a);else mn=min(mn,min(dfs((x-x%2)/2)+(x%2)*d,dfs((x+2-x%2)/2)+(2-x%2)*d)+a);if(x%3==0) mn=min(mn,dfs(x/3)+b);else mn=min(mn,min(dfs((x-x%3)/3)+(x%3)*d,dfs((x+3-x%3)/3)+(3-x%3)*d)+b);if(x%5==0) mn=min(mn,dfs(x/5)+c);else mn=min(mn,min(dfs((x-x%5)/5)+(x%5)*d,dfs((x+5-x%5)/5)+(5-x%5)*d)+c);return dp[x]=mn;
}
void solve()
{dp.clear();cin>>n>>a>>b>>c>>d;dp[0]=0,dp[1]=d;cout<<dfs(n)<<'\n';return;
}
signed main()
{cin.tie(0)->sync_with_stdio(false);int t;cin>>t;while(t--) solve();return 0;
}
T3
50 pts。
LCA 暴力。
思路
直接用并查集维护。
代码
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N=1e6+5;
string s;
int n,fa[N],cnt[N],ans;
vector<int> g[N];
int find(int x){return fa[x]==x?x:fa[x]=find(fa[x]);}
void mark(int u)
{vector<int> ve;int sum=0;for(int v:g[u]){if(s[v]=='R'){int y=find(v);ve.emplace_back(cnt[y]);sum+=cnt[y],ans+=cnt[y];}}int s=0;for(int i:ve) s+=i*(sum-i);ans+=s/2;return;
}
signed main()
{cin.tie(0)->sync_with_stdio(false);cin>>n>>s;s=' '+s;for(int i=1;i<=n;++i) fa[i]=i,cnt[i]=1;for(int i=1,x,y;i<n;++i){cin>>x>>y;if(s[x]=='R'&&s[y]=='R'){int u=find(x),v=find(y);if(u!=v){fa[u]=v;cnt[v]+=cnt[u];}}g[x].emplace_back(y),g[y].emplace_back(x);}for(int i=1;i<=n;++i){if(s[i]=='B'){mark(i);}}cout<<ans;return 0;
}
T4
0 pts。
思路
只有出现了零的时候,这一位才会是零,所以可以使用树状数组统计每一位的答案,每次更新的时候就更新这个数的每一位即可。
代码
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N=1e5+5,mod=1e9+7;
int n,a[N],pw[N];
struct Node{int tr[N];void update(int idx,int val){while(idx<=n){tr[idx]+=val;idx+=idx&-idx;}return;}int query(int idx){int sum=0;while(idx){sum+=tr[idx];idx-=idx&-idx;}return sum;}
}tree[35];
signed main()
{cin.tie(0)->sync_with_stdio(false);cin>>n;for(int i=1;i<=n;++i) cin>>a[i];pw[0]=1;for(int i=1;i<N;++i) pw[i]=(pw[i-1]*2)%mod;for(int i=1;i<=n;++i){for(int j=0;j<=35;++j){if((a[i]>>j)&1) tree[j].update(i,1);}}int q;cin>>q;for(int op,l,r;q--;){cin>>op>>l>>r;if(op==1){for(int j=0;j<=30;++j){if((a[l]>>j)&1) tree[j].update(l,-1);}a[l]=r;for(int j=0;j<=30;++j){if((a[l]>>j)&1) tree[j].update(l,1);}}else{int sum=0;for(int j=0;j<=30;++j){sum=(sum+(pw[tree[j].query(r)-tree[j].query(l-1)]-1)*pw[j]%mod)%mod;}cout<<sum<<'\n';}}return 0;
}