A Super-palindrome 找规律+回文子串 字符串
B Master of Phi 积性函数+欧拉函数 数学题
C Hakase and Nano 博弈论
D Master of Random 找规律+逆元 数学题
J Master of GCD 数论gcd
A Super-palindrome
签到题,因为要每一个奇数长度的子串都要是回文串,所以因该是以三为单位,行程回文串,就是关于奇数位,偶数位和全部讨论,选择变化小的输出,具体的看代码
# include <bits/stdc++.h>
using namespace std;
int j[30];
int o[30];
int q[30];
int main()
{
int T;
scanf("%d",&T);
while(T--){
for(int i=0;i<30;i++){
j[i]=0;
o[i]=0;
q[i]=0;
}
string s;
cin>>s;
int maxj=0,maxo=0,maxq=0;
for(int i=0;i<s.length();i++){
if(i%2==0){
j[s[i]-'a']++;
//cout<<j[s[i]-'a']<<endl;
if(j[s[i]-'a']>maxj) maxj=j[s[i]-'a'];
}else{
o[s[i]-'a']++;
if(o[s[i]-'a']>maxo) maxo=o[s[i]-'a'];
}
q[s[i]-'a']++;
}
int a=s.length()-maxj-maxo;
int b=s.length()-maxq;
//cout<<"####"<<maxj<<" "<<maxo<<endl;
//cout<<"@@@@"<<a<<" "<<b<<endl;
printf("%d\n",min(a,b));
}
return 0;
}
B Master of Phi
# include <bits/stdc++.h>
using namespace std;
typedef long long LL;
const LL mod=998244353;
LL quick_pow(LL a,LL b,LL n)
{
LL ret=1;
while(b)
{
if(b&1) ret=ret*a%n;
a=a*a%n;
b=b/2;
}
return ret%n;
}
int main()
{
int T;
scanf("%d",&T);
while(T--){
int m;
scanf("%d",&m);
LL ans=1;
for(int i=1;i<=m;i++){
LL p,q;
LL cnt=1;
scanf("%lld %lld",&p,&q);
cnt=(((p%mod+((p%mod)*(q%mod))%mod)%mod-q+mod)%mod)%mod;
//cout<<cnt<<endl;
//cout<<"@@@@ "<<ans%mod<<endl;
ans=(((ans*quick_pow(p,q-1,mod))%mod)*cnt)%mod;
//cout<<"@@@"<<" "<<(quick_pow(p,q-1,mod)%mod)<<" "<<cnt%mod<<endl;
}
printf("%d\n",ans);
}
return 0;
}
C Hakase and Nano
博弈论
# include <bits/stdc++.h>
using namespace std;
const int MAXN=1e6+100;
int a[MAXN];
int main()
{
int T;
scanf("%d",&T);
while(T--){
int n,d;
int cnt=0;
int flag;
scanf("%d %d",&n,&d);
//d=1 Hakase
for(int i=1;i<=n;i++){
scanf("%d",&a[i]);
if(a[i]==1) cnt+=a[i];
}
if(d==1){
if(cnt%3==0&&cnt==n) flag=0;
else flag=1;
}else{
if(cnt%3==1&&cnt==n) flag=0;
else if(n%3==1&&cnt==(n-1)) flag=0;
else if(n%3==0&&cnt==(n-1)) flag=0;
else flag=1;
}
if(flag) printf("Yes\n");
else printf("No\n");
}
return 0;
}
D Master of Random
以下是找出的规律,就是因为是要找子树的和,然后我们先不管每一个点到底是什么值,对于一个在n层的节点,他对于整个子树的贡献度是n(然后如果要算子树和的话,那么就是n*ai就好了),关于编号为i的节点,他在哪一层的规律如下,将层数和次数乘起来就是改节点的贡献度。关于整个贡献度的计算规律如下就是,每一层的差就是当前是树形数分别除以当前的层数就是和下一层的差,然后首项是树形数,那么就可以算贡献度了。然后再求逆元就可以了。
#include <bits/stdc++.h>
using namespace std;
using namespace __gnu_cxx;
#define IOC std::ios::sync_with_stdio(false)
typedef long long LL;
typedef unsigned long long uLL;
typedef unsigned int uit;
typedef long double LD;
typedef pair<int,int> pii;
const int INF = 0x3f3f3f3f;
const long double eps = 1e-10;
const double pi = acos(-1.0);
inline LL read()
{
LL X=0,w=0; char ch=0;
while(!isdigit(ch)) {w|=ch=='-';ch=getchar();}
while(isdigit(ch)) X=(X<<3)+(X<<1)+(ch^48),ch=getchar();
return w?-X:X;
}
inline void write(LL x)
{
if(x<0) putchar('-'),x=-x;
if(x>9) write(x/10);
putchar(x%10+'0');
}
//-------head------------
const int maxn = 1e5 + 10;
const LL mod = 998244353;
LL inv[maxn],fact[maxn],pre[maxn];
inline LL quickpow(LL x,LL y){
LL ans = 1;
while(y){
if(y & 1) ans = ans * x % mod;
x = x * x % mod;
y >>= 1;
}
return ans;
}
inline void expow(LL b,LL p,LL &a,LL &k ) {
if(p == 0) {
a = 1; k = 0;
return;
}
expow( p, b % p, k, a );
k -= b / p * a;
return;
}
LL exinv(LL b,LL p ) {
LL a,k;
expow(b,p,a,k);
if(a < 0) a += p;
return a;
}
LL dict[maxn];
int main(){
LL n = 1e5 + 3;
fact[0] = 1;
for(LL i = 1; i <= n; ++i){
fact[i] = fact[i-1] * i % mod;
}
inv[n] = exinv(fact[n],mod);
for(int i = n - 1; i >= 0; --i){
inv[i] = inv[i + 1] * (i + 1) % mod;
}
pre[0] = pre[1] = 1;
for(int i = 2; i <= n; i++ )
pre[i] = (mod - mod / i) * pre[mod % i] % mod;
int t = read();
while(t--){
int n = read();
LL ans = 0,tmp = 0;
for(int i = 1; i <= n; ++i) dict[i] = read();
for(int i = 1; i <= n; ++i){
tmp = (tmp + fact[n - 1] * pre[i - 1] % mod) % mod;
ans = (ans + tmp * dict[i] % mod) % mod;
}
ans = ans * inv[n] % mod;
printf("%lld\n",ans);
}
return 0;
}
J Master of GCD
队友写的,所以没有解释
//J
#include <bits/stdc++.h>
using namespace std;
using namespace __gnu_cxx;
#define IOC std::ios::sync_with_stdio(false)
typedef long long LL;
typedef unsigned long long uLL;
typedef unsigned int uit;
typedef long double LD;
typedef pair<int,int> pii;
const int INF = 0x3f3f3f3f;
const long double eps = 1e-10;
const double pi = acos(-1.0);
inline LL read()
{
LL X=0,w=0; char ch=0;
while(!isdigit(ch)) {w|=ch=='-';ch=getchar();}
while(isdigit(ch)) X=(X<<3)+(X<<1)+(ch^48),ch=getchar();
return w?-X:X;
}
inline void write(LL x)
{
if(x<0) putchar('-'),x=-x;
if(x>9) write(x/10);
putchar(x%10+'0');
}
//-------head------------
const int maxn = 1e5 + 10;
LL pre1[maxn],pre2[maxn];
const LL mod = 998244353;
LL quickpow(LL x,LL y){
LL ans = 1;
while(y){
if(y & 1) ans = ans * x % mod;
x = x * x % mod;
y >>= 1;
}
return ans;
}
void init(){
memset(pre1,0,sizeof pre1);
memset(pre2,0,sizeof pre2);
}
int main(){
int t = read();
while(t--){
int n = read(),m = read();
init();
for(int i = 0; i < m; ++i){
int l = read(),r = read(),x = read();
if(x == 2){
pre1[l]++,pre1[r + 1]--;
}
else{
pre2[l]++,pre2[r + 1]--;
}
}
LL mmin1 = 1e9,mmin2 = 1e9;
for(int i = 1; i <= n; ++i){
pre1[i] += pre1[i - 1];
pre2[i] += pre2[i - 1];
//cout << pre1[i] << " " << pre2[i] << endl;
mmin1 = min(mmin1,pre1[i]);
mmin2 = min(mmin2,pre2[i]);
}
//cout << mmin1 << "?" << mmin2 << endl;
LL ans = quickpow(2,mmin1);
ans = ans * quickpow(3,mmin2) % mod;
cout << ans << endl;
}
return 0;
}