Codeforces Round #403 (Div. 1, based on Technocup 2017 Finals)

Div1单场我从来就没上过分,这场又剧毒,半天才打出B,C挂了好几次最后还FST了,回紫了。

AC:AB Rank:340 Rating:2204-71->2133

Div2.B.The Meeting Place Cannot Be Changed

题目大意:n个人,第i个人位于xi,速度为vi,找到一个点使得所有人到这个点的耗时最小,输出耗时。(n<=60000)

思路:二分答案,知道耗时后可以求出每个人能到达的区间,如果所有区间有交则合法,复杂度O(nlog)。

#include<cstdio>
#include<cmath>
#include<algorithm>
using namespace std;
char B[1<<26],*S=B,C;int X;
inline int read()
{
    while((C=*S++)<‘0‘||C>‘9‘);
    for(X=C-‘0‘;(C=*S++)>=‘0‘&&C<=‘9‘;)X=(X<<3)+(X<<1)+C-‘0‘;
    return X;
}
#define MN 60000
int x[MN+5],v[MN+5];
int main()
{
    fread(B,1,1<<26,stdin);
    int n=read(),i,p;double l=0,r=0x3FFFFFFF,mid,mn,mx,ans;
    for(i=1;i<=n;++i)x[i]=read();
    for(i=1;i<=n;++i)v[i]=read();
    for(p=1;p<=100;++p)
    {
        mid=(l+r)/2;
        for(mn=1e18,mx=-1e18,i=1;i<=n;++i)
            mn=min(mn,x[i]+mid*v[i]),mx=max(mx,x[i]-mid*v[i]);
        if(mx-mn<1e-12)ans=r=mid;
        else l=mid;
    }
    printf("%.12lf",ans);
}

A.Andryusha and Colored Balloons

题目大意:给出一棵n个点的树,距离为2以内的点颜色不能相同,求最小染色方案。(n<=200,000)

思路:每个点对他的儿子染色,每个儿子颜色不与他和他父亲还有染过的儿子颜色相同即可,复杂度O(n)。

#include<cstdio>
char B[1<<26],*S=B,C;int X;
inline int read()
{
    while((C=*S++)<‘0‘||C>‘9‘);
    for(X=C-‘0‘;(C=*S++)>=‘0‘&&C<=‘9‘;)X=(X<<3)+(X<<1)+C-‘0‘;
    return X;
}
#define MN 200000
struct edge{int nx,t;}e[MN*2+5];
int h[MN+5],en,r[MN+5],fa[MN+5],c[MN+5];
inline void ins(int x,int y){e[++en]=(edge){h[x],y};h[x]=en;}
void dfs(int x)
{
    int i,j=0;
    for(i=h[x];i;i=e[i].nx)if(e[i].t!=fa[x])
    {
        while(c[x]==++j||c[fa[x]]==j);
        c[e[i].t]=j;fa[e[i].t]=x;dfs(e[i].t);
    }
}
int main()
{
    fread(B,1,1<<26,stdin);
    int n=read(),i,x,y,rt=0;
    for(i=1;i<n;++i)
    {
        if(++r[x=read()]>r[rt])rt=x;
        if(++r[y=read()]>r[rt])rt=y;
        ins(x,y);ins(y,x);
    }
    printf("%d\n",r[rt]+1);
    dfs(c[1]=1);
    for(i=1;i<=n;++i)printf("%d ",c[i]);
}

B.Innokenty and a Football League

题目大意:n支球队要取名,每支球队有两种选择,要求:1.所有球队名字不能相同;2.如果两支球队第一种选择相同,他们都只能选第二种。(n<=1000)

思路:转化成2-sat模板题就可以了。2-sat构造解我不是很熟练,打了很久。

#include<iostream>
using namespace std;
#define MN 1000
#define MV 2000
#define ME 5000000
string s[MN+5][2],sa,sb;
struct edge{int nx,t;}e[ME*2+5];
int h[MV+5],en,d[MV+5],l[MV+5],cnt,z[MV+5],zn,inz[MV+5],b[MV+5],bn;
int rh[MV+5],r[MV+5],c[MV+5],q[MV+5],qn;
inline void ins(int*h,int x,int y){e[++en]=(edge){h[x],y};h[x]=en;}
void tj(int x)
{
    d[x]=l[x]=++cnt;inz[z[zn++]=x]=1;
    for(int i=h[x];i;i=e[i].nx)
    {
        if(!d[e[i].t])tj(e[i].t);
        if(inz[e[i].t]&&l[e[i].t]<l[x])l[x]=l[e[i].t];
    }
    if(d[x]==l[x])for(++bn;z[zn]!=x;inz[z[zn]]=0)b[z[--zn]]=bn;
}
int main()
{
    int n,i,j,k;
    cin>>n;
    for(i=1;i<=n;++i)
    {
        cin>>sa>>sb;
        s[i][0]=s[i][1]=s[i][0]+sa[0]+sa[1];
        s[i][0]+=sa[2];s[i][1]+=sb[0];
    }
    for(i=1;i<=n;++i)for(j=1;j<=n;++j)if(i!=j)
    {
        if(s[i][0]==s[j][0])ins(h,i,j+n),ins(h,i+n,j+n);
        if(s[i][0]==s[j][1])ins(h,i,j);
        if(s[i][1]==s[j][0])ins(h,i+n,j+n);
        if(s[i][1]==s[j][1])ins(h,i+n,j);
    }
    for(i=1;i<=n<<1;++i)if(!d[i])tj(i);
    for(i=1;i<=n;++i)if(b[i]==b[i+n])return puts("NO"),0;
    puts("YES");
    for(i=1;i<=n<<1;++i)for(j=h[i];j;j=e[j].nx)
        if(b[i]!=b[e[j].t])ins(rh,b[e[j].t],b[i]),++r[b[i]];
    for(i=1;i<=bn;++i)if(!r[i])q[++qn]=i;
    for(i=1;i<=qn;++i)
    {
        if(!c[q[i]])
        {
            for(j=1;j<=n;++j)if(b[j]==q[i])c[b[j+n]]=1;
            for(;j<=n<<1;++j)if(b[j]==q[i])c[b[j-n]]=1;
        }
        for(j=rh[q[i]];j;j=e[j].nx)if(!--r[e[j].t])q[++qn]=e[j].t;
    }
    for(i=1;i<=n;++i)cout<<(c[b[i]]?s[i][1]:s[i][0])<<endl;
}

C.Underground Lab

题目大意:给出n个点m条边的无向联通图,构造k条长度不超过2n/k(向上取整)的路径覆盖所有点。(n,m<=200,000,k<=n)

思路:考虑该图的一颗生成树,dfs一遍,进入节点和从子节点回来时都把当前点加入路径里,就得到一个长度为2n-1的路径覆盖,分成k段输出即可,复杂度O(n)。我输出写的巨丑挂了,非常难受。

AC代码

#include<cstdio>
char B[1<<26],*S=B,C;int X;
inline int read()
{
    while((C=*S++)<‘0‘||C>‘9‘);
    for(X=C-‘0‘;(C=*S++)>=‘0‘&&C<=‘9‘;)X=(X<<3)+(X<<1)+C-‘0‘;
    return X;
}
#define MN 200000
struct edge{int nx,t;}e[MN*2+5];
int f[MN+5],h[MN+5],en,ans[MN*2+5],cnt;
int gf(int k){return f[k]?f[k]=gf(f[k]):k;}
inline void ins(int x,int y){e[++en]=(edge){h[x],y};h[x]=en;}
void dfs(int x,int fa)
{
    ans[++cnt]=x;
    for(int i=h[x];i;i=e[i].nx)if(e[i].t!=fa)
    {
        dfs(e[i].t,x);
        ans[++cnt]=x;
    }
}
int main()
{
    fread(B,1,1<<26,stdin);
    int n,m,k,x,y,i,j;
    n=read();m=read();k=read();
    while(m--)
    {
        x=read();y=read();
        if(gf(x)!=gf(y))f[gf(x)]=gf(y),ins(x,y),ins(y,x);
    }
    dfs(1,0);--cnt;
    for(x=1;x*k<cnt;++x);
    for(i=1;i<=k;++i)
    {
        printf("%d ",x);
        for(j=1;j<=x;++j)printf("%d ",cnt?ans[((i-1)*x+j-1)%cnt+1]:1);
        puts("");
    }
}

D.Axel and Marston in Bitland

题目大意:给出一张n个点m条边的图,边权为0或1,按以下方式构造一个01序列:一开始为0,每次将当前串取反加到原串后面(0,01,0110,01101001……),问从点1出发,按这个01序列走对应边权的边,最多能走多少步,如果超过10^18输出-1。(n<=500,m<=2*n^2)

思路:令s[i][0/1]表示长度为2^i的原串/取反串,则有s[i+1][0]=s[i][0]+s[i][1],s[i+1][1]=s[i][1]+s[i][0],我们把原图按这个方式bitset加速倍增一下,然后DP就可以了,复杂度O(n^3/32*log10^18),时限5s而且cf机子快,非常科学。

#include<cstdio>
#include<cstring>
#include<bitset>
#include<algorithm>
#include<iostream>
using namespace std;
inline int read()
{
    int x;char c;
    while((c=getchar())<‘0‘||c>‘9‘);
    for(x=c-‘0‘;(c=getchar())>=‘0‘&&c<=‘9‘;)x=(x<<3)+(x<<1)+c-‘0‘;
    return x;
}
#define MN 500
#define MK 60
#define INF 1000000000000000000LL
bitset<MN+5> g[MK+5][2][MN+5];
long long f[MK+5][MN+5][2],ans;
int main()
{
    int n,m,i,j,k,x,y;
    n=read();m=read();
    while(m--)
    {
        x=read();y=read();
        g[0][read()][x][y]=1;
    }
    for(k=0;k<MK;++k)for(i=1;i<=n;++i)for(j=1;j<=n;++j)
    {
        if(g[k][0][i][j])g[k+1][0][i]|=g[k][1][j];
        if(g[k][1][i][j])g[k+1][1][i]|=g[k][0][j];
    }
    memset(f,128,sizeof(f));f[k+1][1][0]=0;
    for(k=MK;k>=0;--k)
    {
        for(i=1;i<=n;++i)f[k][i][0]=f[k+1][i][0],f[k][i][1]=f[k+1][i][1];
        for(i=1;i<=n;++i)for(j=1;j<=n;++j)
        {
            if(g[k][0][i][j])f[k][j][1]=max(f[k][j][1],f[k+1][i][0]+(1LL<<k));
            if(g[k][1][i][j])f[k][j][0]=max(f[k][j][0],f[k+1][i][1]+(1LL<<k));
        }
    }
    for(i=1;i<=n;++i)ans=max(ans,max(f[0][i][0],f[0][i][1]));
    cout<<(ans>INF?-1:ans);
}
时间: 2024-08-04 18:11:09

Codeforces Round #403 (Div. 1, based on Technocup 2017 Finals)的相关文章

[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 #602 (Div. 2, based on Technocup 2020 Elimination Round 3

A,有多个线段,求一条最短的线段长度,能过覆盖到所又线段,例如(2,4)和(5,6) 那么我们需要4 5连起来,长度为1,例如(2,10)(3,11),用(3,10) 思路:我们想一下如果题目说的是最长我们肯定是取最小x和最大的y连起来就完事. 但是要求长度最小又得覆盖,那么可以这样想,我们需要把最小的x不断右移到这条线段的y, 最大的左移到x,所以就是最大x-最小y完事 #include <bits/stdc++.h> using namespace std; #define ll long

【cf比赛记录】Codeforces Round #606 (Div. 2, based on Technocup 2020 Elimination Round 4)

比赛传送门 只能说当晚状态不佳吧,有点头疼感冒的症状.也跟脑子没转过来有关系,A题最后一步爆搜没能立即想出来,B题搜索没有用好STL,C题也因为前面两题弄崩了心态,最后,果然掉分了. A:简单数学 B:数学+排序 C:字符串搜索 A // https://codeforces.com/contest/1277/problem/A /* 题意: 给出一个数,求不大于该数的完美整数的个数(完美整数指全是一个数组成的数字,如:111, 333333, 444444, 9, 8888 ...) 分析:

【模拟】 Codeforces Round #434 (Div. 1, based on Technocup 2018 Elimination Round 1) C. Tests Renumeration

题意:有一堆数据,某些是样例数据(假设X个),某些是大数据(假设Y个),但这些数据文件的命名非常混乱.要你给它们一个一个地重命名,保证任意时刻没有重名文件的前提之下,使得样例数据命名为1~X,大数据命名为X+1~X+Y. 先把未使用的名字压进两个栈. 分为三轮:第一轮把占用了对方名字的样例数据以及占用了对方名字的大数据放进两个队列,然后不断反复尝试对这两个队列进行出队操作,每次将占用对方名字的改成一个未被使用的正确名字(从栈里取出),然后将占用的名字压进另一个栈.由于每个数据只会出队一次,所以是

Codeforces Round #468 (Div. 2, based on Technocup 2018 Final Round) D. Peculiar apple-tree

D. Peculiar apple-tree time limit per test 1 second memory limit per test 256 megabytes input standard input output standard output In Arcady's garden there grows a peculiar apple-tree that fruits one time per year. Its peculiarity can be explained i

Codeforces Round #512 (Div. 2, based on Technocup 2019 Elimination Round 1) C. Vasya and Golden Ticket

C. Vasya and Golden Ticket time limit per test 1 second memory limit per test 256 megabytes input standard input output standard output Recently Vasya found a golden ticket - a sequence which consists of nn digits a1a2-ana1a2-an. Vasya considers a ti

cf 20190307 Codeforces Round #543 (Div. 2, based on Technocup 2019 Final Round)

B. Mike and Children time limit per test 2 seconds memory limit per test 256 megabytes input standard input output standard output Mike decided to teach programming to children in an elementary school. He knows that it is not an easy task to interest

Codeforces Round #591 (Div. 2, based on Technocup 2020 Elimination Round 1) 题解

A..B略 C 对当前的值排序,再二分答案,然后对于(i%x==0 && i%y==0)放入大的,再放其他的贪心解决即可. #include<iostream> #include<stdio.h> #include<string.h> #include<algorithm> #include<map> #define LL long long #define lson rt<<1 #define rson rt<

Codeforces Round #596 (Div. 2, based on Technocup 2020 Elimination Round 2)

B2 - TV Subscriptions (Hard Version) 遍历,维护一个set和set<pair<int,int>>即可 1 #include<bits/stdc++.h> 2 using namespace std; 3 typedef long long ll; 4 const int maxn = 1e6+7; 5 const ll mod = 1e9 + 9; 6 #define afdafafafdafaf y1; 7 int ar[maxn]