https://codeforces.com/contest/1996
A
# include <bits/stdc++.h>
using namespace std;
# define int long long
signed main()
{
int t;
cin>>t;
while(t--)
{
int n;
cin>>n;
int s=n/4;
int x=n%4;
cout<<s+(x+1)/2;
cout<<endl;
}
}
B
可以发现每次输出的为i+=k后字母,j同理
# include <bits/stdc++.h>
using namespace std;
# define int long long
string a[1001];
signed main()
{
int t;
cin>>t;
while(t--)
{
int n,k;
cin>>n>>k;
for(int i=1;i<=n;i++)
{
cin>>a[i];
}
for(int i=1;i<=n;i+=k)
{
for(int j=0;j<n;j+=k)
{
cout<<a[i][j];
}
cout<<endl;
}
}
}
C
需要用前缀和处理 用aa bb处理前i个字母中每个字母出现的次数时间复杂度为n*26 每次询问直接输出不同字母数除以2即可 因为不同字母相较于两个字母而言
#include<bits/stdc++.h>
using namespace std;
const int N=2e5+10;
int aa[27][N],bb[27][N];
int main()
{
int t;
cin>>t;
while(t--)
{
int n,q;
cin>>n>>q;
string a,b;
cin>>a>>b;
a=' '+a;
b=' '+b;
for(int i=1;i<=n;i++)
{
int x=a[i]-'a',y=b[i]-'a';
for(int j=0;j<26;j++)
{
if(j==x)
aa[x][i]=aa[x][i-1]+1;
else
aa[j][i]=aa[j][i-1];
if(j==y)
bb[y][i]=bb[y][i-1]+1;
else
bb[j][i]=bb[j][i-1];
}
}
while(q--)
{
int l,r,s=0;
cin>>l>>r;
for(int i=0;i<26;i++)
{
s=s+abs(aa[i][r]-aa[i][l-1]-bb[i][r]+bb[i][l-1]);
}
cout<<s/2<<'\n';
}
}
}
D
暴力枚举 对于两个条件1.a+b+c<=x,2.ab+(a+b)*c<=n 同除(a+b)
可得到c表达式
# include <bits/stdc++.h>
using namespace std;
# define int long long
signed main()
{
int t;
cin>>t;
while(t--)
{
int sum=0;
int n,x;
cin>>n>>x;
for(int a=1;a<x;a++)
{
for(int b=1;b<x-a;b++)
{
if(a*b>n)
break;
else
{
int c=x-a-b;
c=min(c,(n-a*b)/(a+b));
if(c>0)
sum+=c;
}
}
}
cout<<sum<<endl;
}
return 0;
}
E
题意:给一个字符串任选一个区间l到r中任取子区间,当子区间01个数相等时累加答案。
思路:对于子区间我们可以考虑用前缀和处理为1时加一为0时减一,这样当一段前缀和为零时此时01相等,对于小区间被多少大区间覆盖考虑用组合相乘计算(大区间长ans小区间长度为n时此时有ans-n+1种组合)但此时区间个数还是n平方复杂度会超时。因此我们考虑维护一个cnt值,并计算以当前下标j结尾,所有满足条件的起始下标i中,对最后答案的总贡献是多少。一次遍历+map查询即可。这里cnt维护的是左边区间的长度(假设前缀和相同的点x1,x2,x3,x4,x5,我们选择任意两个点都可以作为一个区间,我们发现当x1为左端点 x2x3x4可作为右端点,x2时x3x4x5可作为右端点,组合中x1提供的方案数不变,因此我们可以预处理出右端点,维护后缀和)
# include <bits/stdc++.h>
using namespace std;
# define int long long
const int MOD=1e9+7;
signed main()
{
int t;
cin>>t;
while(t--)
{
string s="";
cin>>s;
int n=s.size();
s=" "+s;
vector<int> P(n + 1, 0);
for (int i = 1; i <= n; i++)
{
P[i] = (s[i] == '1' ? 1 : -1) + P[i - 1];
}
map<int, int> cnt;
int ans = 0;
for (int i = 0; i <= n; i++)
{
ans=(ans + (n - i + 1) * cnt[P[i]]) % MOD;
cnt[P[i]] = (cnt[P[i]] + (i + 1)) % MOD;
}
cout<<ans;
cout<<endl;
}
return 0;
}