AT ABC 418
ATcoder ABC418
A - I'm a teapot
水题,懒得说。
code
#include <bits/stdc++.h>
#define i8 __int128
#define int long long
#define fuck inline
#define lb long double
using namespace std;
// typedef long long ll;
const int N=1e7+5,mod=998244353;
const int INF=1e9+7;
const int inf=LONG_LONG_MAX/4;
// const int mod1=469762049,mod2=998244353,mod3=1004535809;
// const int G=3,Gi=332748118;
// const int M=mod1*mod2;
fuck int read()
{
int x=0,f=1;
char c=getchar();
while(c<'0'||c>'9'){if(c=='-'){f=-1;}c=getchar();}
while(c>='0'&&c<='9'){x=(x<<3)+(x<<1)+(c-'0');c=getchar();}
return x*f;
}
fuck void write(int x)
{
if(x<0){putchar('-');x=-x;}
if(x>9) write(x/10);
putchar(x%10+'0');
}
int n;
string s;
fuck void solve()
{
cin>>n>>s;s=' '+s;
if(n<3){cout<<"No"<<endl;return;}
if(s[n]=='a'&&s[n-1]=='e'&&s[n-2]=='t')cout<<"Yes"<<endl;
else cout<<"No"<<endl;
}
signed main()
{
solve();
return 0;
}
// 6666 66666 666666
// 6 6 6 6 6
// 6 6 6666 6
// 6 6 6 6 6
// 6666 6 6 6666666
B - You're a teapot
暴力枚举两个 $ "t" $ ,然后 $ check $ 一下,$ O(n^{3}) $ 能过,依旧水题。
code
#include <bits/stdc++.h>
#define i8 __int128
#define int long long
#define fuck inline
#define lb long double
using namespace std;
// typedef long long ll;
const int N=1e7+5,mod=998244353;
const int INF=1e9+7;
const int inf=LONG_LONG_MAX/4;
// const int mod1=469762049,mod2=998244353,mod3=1004535809;
// const int G=3,Gi=332748118;
// const int M=mod1*mod2;
fuck int read()
{
int x=0,f=1;
char c=getchar();
while(c<'0'||c>'9'){if(c=='-'){f=-1;}c=getchar();}
while(c>='0'&&c<='9'){x=(x<<3)+(x<<1)+(c-'0');c=getchar();}
return x*f;
}
fuck void write(int x)
{
if(x<0){putchar('-');x=-x;}
if(x>9) write(x/10);
putchar(x%10+'0');
}
int n;
string s;
fuck void solve()
{
cin>>s;s=' '+s;
double ans=0.0;
for(int i=1;i<s.size();i++)
{
if(s[i]=='t')
{
for(int j=i+1;j<=s.size();j++)
{
if(s[j]=='t')
{
int sum=0;
for(int k=i;k<=j;k++)
{
if(s[k]=='t')sum++;
}
ans=max(ans,1.0*(sum-2)/(j-i-1));
}
}
}
}
printf("%.10lf\n",ans);
}
signed main()
{
solve();
return 0;
}
C - Flush
开题时被翻译搞懵逼了。
简述题意
一共有 $ n $ 种口味的茶包,对应编号 $ 1~i $ ,第 $ i $ 种口味有 $ a_{i} $ 个。
- 游戏难度 $ b $ 需要选择一个 $ x(b \leq x \leq \displaystyle \sum_{i=1}^{n}a_{i}) $ ,然后庄家有选择 $ x $ 个茶包给玩家;
- 玩家需要从 $ x $ 个茶包中选出 $ b $ 个相同的口味的茶包才能获胜;
- 庄家会尽量选择让玩家无法选出 $ b $ 个相同口味的茶包;
- 答案要求输出最小的 $ x $ ,如果无解输出 $ -1 $ 。
问题分析
- 庄家会使每种口味的茶包不超过 $ b-1 $ 个。所以所有口味茶包的最大可能数量总和为 $ S(b)= \displaystyle \sum_{i=1}^{n}min(a_{i},b-1) $ 。
- 如果 $ x>S(b) $ ,那么无论庄家如何选择必然有一种口味存在 $ b $ 个。
优化查找
- 首先将茶包 $ a $ 数组排序,并计算前缀和;
- 对于每一个 $ b $ ,二分查找找到第一个茶包个数大于 $ b-1 $ 的位置 $ pos $ ,于是就可以快速计算 $ S(b)=pre_{pos}+c \times (n-pos) $ 。
时间复杂度:$ O(n \cdot log(n)+ m \cdot log(n))$
code
#include <bits/stdc++.h>
#define i8 __int128
#define int long long
#define fuck inline
#define lb long double
using namespace std;
// typedef long long ll;
const int N=1e7+5,mod=998244353;
const int INF=1e9+7;
const int inf=LONG_LONG_MAX/4;
// const int mod1=469762049,mod2=998244353,mod3=1004535809;
// const int G=3,Gi=332748118;
// const int M=mod1*mod2;
fuck int read()
{
int x=0,f=1;
char c=getchar();
while(c<'0'||c>'9'){if(c=='-'){f=-1;}c=getchar();}
while(c>='0'&&c<='9'){x=(x<<3)+(x<<1)+(c-'0');c=getchar();}
return x*f;
}
fuck void write(int x)
{
if(x<0){putchar('-');x=-x;}
if(x>9) write(x/10);
putchar(x%10+'0');
}
int m,n,sum=0;
int a[N];
int pre[N];
fuck void solve()
{
cin>>n>>m;
for(int i=0;i<n;i++)
{
cin>>a[i];
sum+=a[i];
}
sort(a,a+n);
memset(pre,0,sizeof(pre));
for(int i=0;i<n;i++)pre[i+1]=pre[i]+a[i];
while(m--)
{
int b;cin>>b;
int c=b-1;
int pos=upper_bound(a,a+n,c)-a;
int ans=max(b,pre[pos]+c*(n-pos)+1);
if(ans<=sum)
{
cout<<ans<<endl;
}
else cout<<-1<<endl;
}
}
signed main()
{
solve();
return 0;
}
// 6666 66666 666666
// 6 6 6 6 6
// 6 6 6666 6
// 6 6 6 6 6
// 6666 6 6 6666666
D - XNOR Operation
分析问题
- 经过使用神秘的观察法,可以发现这合并操作不就是异或吗?
- 再通过首烷样例的方法,可以总结出:$ \ $
- 如果字符串长度为奇数,最终结果等于所有字符的异或和;
- 如果字符串长度为偶数,最终结果等于所有字符异或和再异或上 $ 1 $ ;
处理子串
考虑处理单个子串,根据这里子串定义我们可以采取以下策略优化计算:
- 使用前缀异或和数组 $ pre $ 计算任意子串的异或和,定义:$ pre_{0}=0,pre_{i}=pre_{0} \bigoplus pre_{1} \bigoplus … \bigoplus pre[i] $ ;
- 对一个子串 $ [i,j] $ 就可以采用 $ pre_{j} \bigoplus pre_{i-1} $ 快速计算出;
- 根据子串长度的奇偶性,就可以对条件进行转换:$ \ $
- 长度为奇数时:$ pre_{j} \bigoplus pre_{i-1}=1 \rightarrow pre_{j} = pre_{i-1} \bigoplus 1 $ ;
- 长度为偶数时:$ pre_{j} \bigoplus pre_{i-1}=0 \rightarrow pre_{j} = pre_{i-1}$ ;
- 将前缀值按奇偶性分类,计算前缀异或和出现的次数,以便快速计算满足要求的 $ (i,j) $ 对数。
动态计算答案
遍历前缀位置 $ i \in [1,n] $ ,根据 $ i $ 的奇偶性:$ \ $
- 如果 $ i $ 是奇数,统计前面偶数位置中 $ pre_{j}=pre_{i} $ (长度为偶数)数量和奇数位置中 $ pre_{j}=pre_{i} \bigoplus 1 $ (长度为奇数)的数量;
- 如果 $ i $ 是偶数,统计前面奇数位置中 $ pre_{j}=pre_{i} $ (长度为偶数)数量和偶数位置中 $ pre_{j}=pre_{i} \bigoplus 1 $ (长度为奇数)的数量;
最后更新一下奇偶异或前缀出现次数。
code
#include <bits/stdc++.h>
#define i8 __int128
#define int long long
#define fuck inline
#define lb long double
using namespace std;
// typedef long long ll;
const int N=1e7+5,mod=998244353;
const int INF=1e9+7;
const int inf=LONG_LONG_MAX/4;
// const int mod1=469762049,mod2=998244353,mod3=1004535809;
// const int G=3,Gi=332748118;
// const int M=mod1*mod2;
fuck int read()
{
int x=0,f=1;
char c=getchar();
while(c<'0'||c>'9'){if(c=='-'){f=-1;}c=getchar();}
while(c>='0'&&c<='9'){x=(x<<3)+(x<<1)+(c-'0');c=getchar();}
return x*f;
}
fuck void write(int x)
{
if(x<0){putchar('-');x=-x;}
if(x>9) write(x/10);
putchar(x%10+'0');
}
int n;
int a[N];
int pre1[3]={1,0};
int pre2[3]={0,0};
fuck void solve()
{
cin>>n;int ans=0,pre=0;
string s;cin>>s;s=' '+s;
for(int i=1;i<=n;i++)
{
if(s[i]=='1')pre^=1;
else pre^=0;
if(i%2==0)
{
ans+=(pre1[pre]+pre2[pre^1]);
pre1[pre]++;
}
else
{
ans+=(pre2[pre]+pre1[pre^1]);
pre2[pre]++;
}
}
cout<<ans<<endl;
}
signed main()
{
solve();
return 0;
}
// 6666 66666 666666
// 6 6 6 6 6
// 6 6 6666 6
// 6 6 6 6 6
// 6666 6 6 6666666
E - Trapezium
思路
枚举点对计算斜率,对于两条斜率相等的直线必然能形成一个梯形,用map存一下斜率的分子和分母。
然后对于一个平行四边形发现其被重复计算一次,考虑如何计算平行四边形的数量。根据平行四边形的性质,可以推断出如果两个线段的中点相同,那么这两条线段必然可以成为一个平行四边形的对角线,用map维护点对即可,需要使用浮点型。
code
code
#include <bits/stdc++.h>
#define i8 __int128
#define int long long
#define fuck inline
#define lb long double
using namespace std;
// typedef long long ll;
const int N=2e3+5,mod=998244353;
const int INF=1e9+7;
const int inf=LONG_LONG_MAX/4;
// const int mod1=469762049,mod2=998244353,mod3=1004535809;
// const int G=3,Gi=332748118;
// const int M=mod1*mod2;
fuck int read()
{
int x=0,f=1;
char c=getchar();
while(c<'0'||c>'9'){if(c=='-'){f=-1;}c=getchar();}
while(c>='0'&&c<='9'){x=(x<<3)+(x<<1)+(c-'0');c=getchar();}
return x*f;
}
fuck void write(int x)
{
if(x<0){putchar('-');x=-x;}
if(x>9) write(x/10);
putchar(x%10+'0');
}
int n;
map<pair<int,int>,int>mp;
map<pair<double,double>,int>mp1;
#define fr first
#define se second
fuck pair<int,int> calc(pair<int,int>a,pair<int,int>b)
{
int tmp1=a.se-b.se;
int tmp2=a.fr-b.fr;
// cout<<"ccccccccc"<<endl;
int g=__gcd(tmp1,tmp2);
// cout<<"ddddddddddd"<<endl;
pair<int,int>frz;
// cout<<g<<" "<<endl;
frz.fr=tmp1/g;
frz.se=tmp2/g;
return frz;
}
pair<int,int>a[N];
fuck void solve()
{
// cout<<"aaaaaaaaaaaaaaa"<<endl;
int n;n=read();int ans=0;
for(int i=1;i<=n;i++)a[i].fr=read(),a[i].se=read();
// cout<<"bbbbbbbbbbbbbbb"<<endl;
for(int i=1;i<=n;i++)
for(int j=i+1;j<=n;j++)
{
ans+=mp[calc(a[i],a[j])];
mp[calc(a[i],a[j])]++;
}
// cout<<ans<<endl;
// cout<<"ccccccccccccccccccc"<<endl;
for(int i=1;i<=n;i++)
for(int j=i+1;j<=n;j++)
{
double tmp1=1.0*(a[i].fr+a[j].fr)/2;
double tmp2=1.0*(a[i].se+a[j].se)/2;
// cout<<tmp1<<" "<<tmp2<<" "<<mp1[{tmp1,tmp2}]<<endl;
ans-=mp1[{tmp1,tmp2}];
mp1[{tmp1,tmp2}]++;
}
cout<<ans<<endl;
}
signed main()
{
// ios::sync_with_stdio(false);
// cin.tie(0); cout.tie(0);
// int QwQ=read();
// int fuckccf=read();
// while(QwQ--)solve();
solve();
return 0;
}
// 6666 66666 666666
// 6 6 6 6 6
// 6 6 6666 6
// 6 6 6 6 6
// 6666 6 6 6666666
完结收工!!!!!

看完点赞,养成习惯
\(\Downarrow\Downarrow\Downarrow\Downarrow\Downarrow\Downarrow\Downarrow\Downarrow\Downarrow\Downarrow\Downarrow\Downarrow\Downarrow\Downarrow\Downarrow\Downarrow\Downarrow\Downarrow\Downarrow\Downarrow\Downarrow\Downarrow\Downarrow\Downarrow\Downarrow\)

浙公网安备 33010602011771号