Codeforces Round #522 Div. 1 没打记

  开场被A劝退,写了得有50min于是不敢交了。unrated了喜闻乐见。

  A:瞎猜都能猜到如果要走到那条直线上,进入直线的点横坐标或纵坐标与起点相同,离开直线的点横坐标或纵坐标与终点相同,证明脑补一下比较显然。看错题以为到直线上的那个点必须是整点,于是搞了半天exgcd。然而就算这样也不至于写这么长时间啊根本不知道自己在干啥。

#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstdlib>
#include<cstring>
#include<algorithm>
using namespace std;
#define ll long long
#define double long double
char getc(){char c=getchar();while ((c<‘A‘||c>‘Z‘)&&(c<‘a‘||c>‘z‘)&&(c<‘0‘||c>‘9‘)) c=getchar();return c;}
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<<1)+(x<<3)+(c^48),c=getchar();
    return x*f;
}
double ans,A,B,C,lx,ly,rx,ry;
double dis_m(double x,double y,double p,double q){return fabs(x-p)+fabs(y-q);}
double dis_o(double x,double y,double p,double q){return sqrt((p-x)*(p-x)+(y-q)*(y-q));}
struct data{double x,y;
}a[2],b[2];
int main()
{
#ifndef ONLINE_JUDGE
    freopen("a.in","r",stdin);
    freopen("a.out","w",stdout);
#endif
    A=read(),B=read(),C=read();
    lx=read(),ly=read(),rx=read(),ry=read();
    ans=fabs(rx-lx)+fabs(ry-ly);
    if (A&&B)
    {
        a[0].x=lx,a[0].y=(-C-A*lx)/B;
        a[1].y=ly,a[1].x=(-C-B*ly)/A;
        b[0].x=rx,b[0].y=(-C-A*rx)/B;
        b[1].y=ry,b[1].x=(-C-B*ry)/A;
        for (int i=0;i<2;i++)
            for (int j=0;j<2;j++)
            ans=min(ans,dis_m(lx,ly,a[i].x,a[i].y)+dis_o(a[i].x,a[i].y,b[j].x,b[j].y)+dis_m(b[j].x,b[j].y,rx,ry));
    }
    printf("%.6Lf\n",ans);
    return 0;
}

  B:题意比较奇怪,做法相当显然,肯定要保证所有满足询问给出的条件的子集都只包含同一单一数字,类似背包的算一发方案数就行了,可以取个模。看起来询问补集也是一种询问方式,不过稍微想一下就知道是没有必要的。但这带来一种特殊情况,即只有两种数字时输出n。

#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstdlib>
#include<cstring>
#include<algorithm>
using namespace std;
#define ll long long
#define N 110
#define P 998244353
char getc(){char c=getchar();while ((c<‘A‘||c>‘Z‘)&&(c<‘a‘||c>‘z‘)&&(c<‘0‘||c>‘9‘)) c=getchar();return c;}
int gcd(int n,int m){return m==0?n:gcd(m,n%m);}
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<<1)+(x<<3)+(c^48),c=getchar();
    return x*f;
}
int n,a[N],ans;
int f[N][N*N],C[N][N];
int main()
{
#ifndef ONLINE_JUDGE
    freopen("b.in","r",stdin);
    freopen("b.out","w",stdout);
#endif
    n=read();
    for (int i=1;i<=n;i++) a[i]=read();
    f[0][0]=1;
    for (int i=1;i<=n;i++)
        for (int k=i;k>=1;k--)
            for (int j=10000;j>=a[i];j--)
            f[k][j]=(f[k][j]+f[k-1][j-a[i]])%P;
    C[0][0]=1;
    for (int i=1;i<=n;i++)
    {
        C[i][0]=C[i][i]=1;
        for (int j=1;j<i;j++)
        C[i][j]=(C[i-1][j-1]+C[i-1][j])%P;
    }
    sort(a+1,a+n+1);
    int cnt=0;
    for (int i=1;i<=n;i++)
    {
        int t=i;
        cnt++;
        while (t<n&&a[t+1]==a[i]) t++;
        for (int j=i;j<=t;j++)
        if (C[t-i+1][j-i+1]==f[j-i+1][(j-i+1)*a[i]]) ans=max(ans,j-i+1);
        i=t;
    }
    if (cnt==2) {cout<<n;return 0;}
    cout<<ans;
    return 0;
}

  C:考虑清楚最大匹配唯一究竟是什么。冷静分析能够发现其充要条件是该树只包含一个点或存在完美匹配。充分性比较显然,对于必要性,考虑如果不存在完美匹配,最大匹配中未匹配点的周围一定存在匹配点,可以将该匹配点改为与未匹配点匹配而匹配数不变,于是方案不唯一。那么就可以瞎dp了,我自己的做法是设f[i][0/1/2]分别表示 割开i与父亲的边,子树内的森林都满足条件/不割开i与父亲的边,i不与子树内点匹配/不割开i与父亲的边,i与子树内点匹配 的删边方案数,比较显然的有f[i][2]=Σ(f[k][1]·∏(f[son][0]+f[son][2])) (k为i某个儿子,son为除k以外i的儿子们) f[i][0]=f[i][2]+∏f[son][0] f[i][1]=∏(f[son][0]+f[son][2])。

#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstdlib>
#include<cstring>
#include<algorithm>
using namespace std;
#define ll long long
#define N 300010
#define P 998244353
char getc(){char c=getchar();while ((c<‘A‘||c>‘Z‘)&&(c<‘a‘||c>‘z‘)&&(c<‘0‘||c>‘9‘)) c=getchar();return c;}
int gcd(int n,int m){return m==0?n:gcd(m,n%m);}
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<<1)+(x<<3)+(c^48),c=getchar();
    return x*f;
}
int n,p[N],f[N][3],pre[N],suf[N],t;
struct data{int to,nxt;
}edge[N<<1];
void addedge(int x,int y){t++;edge[t].to=y,edge[t].nxt=p[x],p[x]=t;}
void dfs(int k,int from)
{
    f[k][0]=f[k][1]=1;f[k][2]=0;int son=0;pre[0]=1;
    for (int i=p[k];i;i=edge[i].nxt)
    if (edge[i].to!=from) dfs(edge[i].to,k);
    for (int i=p[k];i;i=edge[i].nxt)
    if (edge[i].to!=from) pre[++son]=(f[edge[i].to][0]+f[edge[i].to][2])%P;
    suf[son+1]=1;for (int i=1;i<=son;i++)suf[i]=pre[i];
    for (int i=1;i<=son;i++) pre[i]=1ll*pre[i-1]*pre[i]%P;
    for (int i=son;i>=1;i--) suf[i]=1ll*suf[i+1]*suf[i]%P;
    int cnt=0;
    for (int i=p[k];i;i=edge[i].nxt)
    if (edge[i].to!=from)
    {
        cnt++;
        f[k][2]=(f[k][2]+1ll*f[edge[i].to][1]*pre[cnt-1]%P*suf[cnt+1])%P;
        f[k][0]=1ll*f[k][0]*f[edge[i].to][0]%P;
    }
    f[k][0]=(f[k][0]+f[k][2])%P;
    f[k][1]=pre[son];
}
int main()
{
#ifndef ONLINE_JUDGE
    freopen("c.in","r",stdin);
    freopen("c.out","w",stdout);
#endif
    n=read();
    for (int i=1;i<n;i++)
    {
        int x=read(),y=read();
        addedge(x,y),addedge(y,x);
    }
    dfs(1,1);
    cout<<f[1][0];
    return 0;
}

  D:https://www.cnblogs.com/Gloid/p/9874122.html 可能和这个题比较相似。倍增算出每只鹦鹉的影响区间扩展2k次能到哪即可。只是口胡,不知道有没有锅。

原文地址:https://www.cnblogs.com/Gloid/p/9985267.html

时间: 2024-08-02 09:26:35

Codeforces Round #522 Div. 1 没打记的相关文章

Educational Codeforces Round 58 Div. 2 自闭记

明明多个几秒就能场上AK了.自闭. A:签到. #include<iostream> #include<cstdio> #include<cmath> #include<cstdlib> #include<cstring> #include<algorithm> using namespace std; #define ll long long char getc(){char c=getchar();while ((c<'A'

Codeforces Round #545 (Div. 2) 掉分记

每次CF后,我的rating下降,掉分让我悲痛欲绝 ——题记 ### 前言 这次 CF 时间可谓是极好的,17:05 开始,时长 2h 30min. 4:40 回到家,开电脑. 在看了一会书后,比赛开始了. ### 正文 首先,第一个掉分的 flag 出现了! 卡,卡,卡! CF 又双叒叕卡了! 1分钟过去了…… 2分钟过去了…… 3分钟过去了…… Dashboard 一直打不开.. 当时间已经接近 17:10 分的时候,我终于打开了 A 题.. 然而,这还并不是我掉分的所有原因. 先迅速浏览了

[Codeforces Round #522 (Div. 2, based on Technocup 2019 Elimination Round 3)][C. Playing Piano]

http://codeforces.com/contest/1079/problem/C 题目大意:给出一个数列a[n],让构造一个满足下列条件的数列b[n]:如果a[i]>a[i-1]那么b[i]>b[i-1],如果a[i]<a[i-1]那么b[i]<b[i-1],如果a[i]==a[i-1],那么b[i]!=b[i-1].其中1<=b[i]<=5  1<=a[i]<=2*1e5. 题解:dp[i][j]表示在位置i处取j时是否成立,如果成立则dp[i][

Codeforces Round #545 Div. 1自闭记

A:求出该行该列各有多少个比其小的取max,该行该列各有多少个比其大的取max,加起来即可. #include<iostream> #include<cstdio> #include<cmath> #include<cstdlib> #include<cstring> #include<algorithm> using namespace std; #define ll long long #define N 1010 char ge

Codeforces Round #535 (Div. 3)小上分记

Codeforces Round #535 (Div. 3)小上分记 前言 被拉去买新年衣服了,导致半小时后才进场. 虽然做了4道题,但是rating还是涨得不多. 用predictor看了rating变化后心灰意冷,不看E题了. A ...800的难度. B 本来还在想要不要用什么STL.后来发现直接用桶就行了.然后就可以水过了. C 题意差点理解不了. 就6种情况都去考虑一下,找最小代价的即可.不要考虑少了. 每次都是\(O(n)\)的,所以能搞. D 贪心地换字母即可. E 坑.待填. 原

Codeforces Round #354 (Div. 2) ABCD

Codeforces Round #354 (Div. 2) Problems # Name     A Nicholas and Permutation standard input/output 1 s, 256 MB    x3384 B Pyramid of Glasses standard input/output 1 s, 256 MB    x1462 C Vasya and String standard input/output 1 s, 256 MB    x1393 D T

Codeforces Round 239 Div 1

都怪自己太懒了 这段时间比赛参加了大部分,但是一直都没写题解,趁这几天没事,计划把这段时间的题解都补上. 上一次比赛(248)终于升到了div1,所以从这次开始就开始写div1了. A. Triangle There is a right triangle with legs of length a and b. Your task is to determine whether it is possible to locate the triangle on the plane in such

Codeforces Round #366 (Div. 2) ABC

Codeforces Round #366 (Div. 2) A I hate that I love that I hate it水题 1 #I hate that I love that I hate it 2 n = int(raw_input()) 3 s = "" 4 a = ["I hate that ","I love that ", "I hate it","I love it"] 5 fo

Codeforces Round #489 (Div. 2)

Codeforces Round #489 (Div. 2) A. Nastya and an Array #include <bits/stdc++.h> #define rep(i,a,b) for(int i=a;i<=b;++i) #define frep(i,a,b) for(int i=a;i>=b;--i) #define mem(W) memset(W,0,sizeof(W)) #define pb push_back typedef long long ll; c