To_Heart—题解——「abc177」 题解报告
目录
A.Don't be late
题解
按题意模拟即可
#include<bits/stdc++.h>
using namespace std;
#define db double
db d,t,s;
int main(){
cin>>d>>t>>s;
db ans=d/s;
if(ans<=t){
printf("Yes\n");
return 0;
}
cout<<"No"<<endl;
return 0;
}
B.Substring
题解
暴力O( n 2 n^2 n2)模拟即可
#include<bits/stdc++.h>
using namespace std;
char a[2005];
char b[2005];
char aa[2005],bb[2005];
int len1,len2;
int main(){
cin>>(aa+1);
cin>>(bb+1);
len1=strlen(aa+1),len2=strlen(bb+1);
if(len1<len2){
for(int i=1;i<=len2;i++){
a[i]=bb[i];
}
for(int i=1;i<=len1;i++){
b[i]=aa[i];
}
swap(len1,len2);
}
else{
for(int i=1;i<=len1;i++){
a[i]=aa[i];
}
for(int i=1;i<=len2;i++){
b[i]=bb[i];
}
}
int ans=len1+len2;
for(int i=1;i<=len1-len2+1;i++){
int now=len2;
for(int j=1;j<=len2;j++){
if(a[i+j-1]==b[j]) now--;
}
ans=min(now,ans);
}
cout<<ans<<endl;
}
C.Sum of product of pairs
题解
乘法分配律结合即可
#include <bits/stdc++.h>
using namespace std;
#define u unsigned
#define ll long long
#define ull u ll
const ull Mod = 1e9 + 7;
ll sum = 0;
ll ans = 0;
int n;
ll a[200005];
int main() {
cin >> n;
for (int i = 1; i <= n; i++) {
scanf("%lld", &a[i]);
sum += a[i];
}
for (int i = 1; i <= n; i++) {
ans += (a[i] * ((sum - a[i]) % Mod));
ans %= Mod;
sum -= a[i];
}
printf("%lld", ans);
return 0;
}
D.Friends
题解
并查集,找出每个人有多少的朋友,每两个朋友必须分在两个不同的组合,所以要分的组合即是最多的朋友集合的人数
#include<bits/stdc++.h>
using namespace std;
int pre[200005];
int sum[200005];
int n,m;
void Init(){
for(int i=1;i<=n;i++){
pre[i]=i;
sum[i]=1;
}
}
int Find(int x){
if(pre[x]!=x){
pre[x]=Find(pre[x]);
}
return pre[x];
}
void Join(int x,int y){
int fx=Find(x),fy=Find(y);
if(pre[fx]!=fy){
pre[fx]=fy;
sum[fy]+=sum[fx];
}
}
int main(){
cin>>n>>m;
Init();
for(int i=1;i<=m;i++){
int x,y;
scanf("%d%d",&x,&y);
Join(x,y);
}
int ans=0;
for(int i=1;i<=n;i++){
ans=max(ans,sum[i]);
}
printf("%d",ans);
return 0;
}
E.Coprime
题解
按题意模拟即可
#include<bits/stdc++.h>
using namespace std;
int n;
int a[1000005];
int pre[1000005],tot=0;
int f[1000005];
int flag=0;
int Gcd(int a,int b){
if(b==0)
return a;
return Gcd(b,a%b);
}
void SZS(){
for(int i=2;i<=1000000;i++){
if(!f[i]){
pre[++tot]=i;
for(int j=i+i;j<=1000000;j+=i)
f[j]=1;
}
}
}
int main(){
cin>>n;
SZS();
// for(int i=1;i<=tot;i++){
// printf("%d ",pre[i]);
// }
memset(f,0,sizeof f);
int G;
for(int i=1;i<=n;i++){
scanf("%d",&a[i]);
int now=a[i];
for(int j=1;j<=tot&&pre[j]<=sqrt(a[i]);j++){
if(flag) break;
if(a[i]%pre[j]==0)
f[pre[j]]++;
if(f[pre[j]]>=2)
flag=1;
while(a[i]%pre[j]==0){
a[i]/=pre[j];
}
}
if(a[i]>1){
f[a[i]]++;
if(f[a[i]]>=2) flag=1;
}
if(i==1)
G=now;
else{
G=Gcd(now,G);
}
}
if(!flag&&G==1){
printf("pairwise coprime");
}
else if(G==1){
printf("setwise coprime");
}
else {
printf("not coprime");
}
return 0;
}
F I hate Shortest Path Problem
题解
定义一颗线段树t,维护第1行到第i行横着走的所需的最短距离;
定义now,表示从第一行能到达第 i行的列号的最小值。
假设当前的行为i,如果now在l[i]到r[i]之间,且因为now是最小值,说明即使可以到达当前层,那么到达的列数也一定在r[i]的后面。既然无法通过上一层的l[i]~r[i]转移到当前层,索性将其全部变为无法取到的值。
如果now<l[i],说明对于l[i]以前的列是没有影响的,但在l[i]~r[i]的转换方式只能先到同一层的前面几列,再转换到l[i]到r[i]所对应的列。
如果now>r[i],则没有半毛钱影响。
#include<bits/stdc++.h>
using namespace std;
#define ll long long
struct Segment_Tree{
int l,r;
int ans;
int add;
}t[800005];
int n,m;
const int INF=0x3f3f3f3f;
void Spread(int p){
if(t[p].add){
t[2*p].ans=t[p].l-t[p].add;
t[2*p+1].ans=((t[p].l+t[p].r)>>1)+1-t[p].add;
t[2*p].add=t[p].add;
t[2*p+1].add=t[p].add;
t[p].add=0;
}
}
void Build_Tree(int p,int l,int r){
t[p].l=l;
t[p].r=r;
t[p].ans=0;
t[p].add=0;
if(l==r) return;
int mid=(l+r)>>1;
Build_Tree(p*2,l,mid);
Build_Tree(p*2+1,mid+1,r);
}
void Change_Tree(int p,int l,int r,int val){
if(l<=t[p].l&&t[p].r<=r){
t[p].ans=t[p].l-val;
t[p].add=val;
return;
}
Spread(p);
int mid=(t[p].r+t[p].l)>>1;
if(l<=mid)
Change_Tree(p*2,l,r,val);
if(mid<r)
Change_Tree(p*2+1,l,r,val);
t[p].ans=min(t[p*2].ans,t[p*2+1].ans);
}
int Find_Tree(int p,int k){
if(t[p].l==t[p].r)
return k-t[p].ans;
Spread(p);
int mid=(t[p].l+t[p].r)>>1;
if(k<=mid)
return Find_Tree(p*2,k);
else
return Find_Tree(p*2+1,k);
}
int main(){
cin>>n>>m;
int now=1;
Build_Tree(1,1,m);
for(int i=1;i<=n;i++){
int l,r;
scanf("%d%d",&l,&r);
if(now<l)
Change_Tree(1,l,r,Find_Tree(1,l-1));
else if(now>=l&&now<=r){
Change_Tree(1,now,r,-INF);
now=r+1;
}
if(now>m){
printf("-1\n");
continue;
}
printf("%d\n",i+t[1].ans);
}
return 0;
}