Helvetic Coding Contest 2019

题目链接:戳我

小注:其中部分(大括号不换行的)代码是BLUESKY007神仙写的。
小注2:如果可以的话,B2,C2,E3明天更。

CF1184 A1

直接枚举,以根号的时间复杂度判断即可。注意x,y都是正整数。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#define MAXN 100010
#define ll long long
using namespace std;
ll r;
inline ll calc(ll x)
{
    ll cur=r-x*x-x-1;
    if(cur<=0) return -1;
    if(cur%(2*x)==0) return cur/(2*x);
    else return -1;
}
int main()
{
    #ifndef ONLINE_JUDGE
    freopen("ce.in","r",stdin);
    #endif
    scanf("%lld",&r);
    for(ll i=1;i<=1000000;i++)
    {
        if(calc(i)>0)
        {
            printf("%lld %lld\n",i,calc(i));
            return 0;
        }
    }
    printf("NO\n");
    return 0;
}

CF1184 A2

我们可以知道对于k,如果\(gcd(k,n)\)可以的话,那么k一定也可以。
所以我们就把枚举k才能计算的东西降低到了log的时间复杂度。
然后按每次长度为k在环上往后跳,直到跳到一个点第二次。在这期间,显然其中为1的边的个数为偶数才是可行方案。
那么直接把它们异或起来就行了。QAQ

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#define MAXN 200010
using namespace std;
int n,ans;
int cnt[MAXN],done[MAXN];
char s[MAXN];
int main()
{
    #ifndef ONLINE_JUDGE
    freopen("ce.in","r",stdin);
    #endif
    scanf("%d",&n);
    scanf("%s",s);
    for(int i=1;i<=n;i++) cnt[__gcd(i,n)]++;
    for(int i=1;i<=n;i++)
    {
        if(cnt[i])
        {
            bool flag=false;
            memset(done,0,sizeof(done));
            for(int j=0;j<n;j++)
            {
                if(!done[j])
                {
                    int cur_ans=0,x=j;
                    while(!done[x])
                    {
                        cur_ans^=(s[x]-'0');
                        done[x]=1;
                        x=(x+i)%n;
                    }
                    if(cur_ans) flag=true;
                }
            }
            if(!flag) ans+=cnt[i];
        }
    }
    printf("%d\n",ans);
    return 0;
}

CF1184 B1

二分。

#include<bits/stdc++.h>

using namespace std;

const int N=1e5+5;

struct base{
    int d,g,id;
    bool operator<(const base&rhs)const{
        return d!=rhs.d?d<rhs.d:id<rhs.id;
    }
}ba[N];

int s,b,a[N];

long long sum[N];

int bs(int l,int r,int u){
    if(l==r){
        return l;
    }
    int mid=(l+r+1)>>1;
    if(ba[mid].d<=u){
        return bs(mid,r,u);
    }
    else{
        return bs(l,mid-1,u);
    }
}

int main(){
    scanf("%d%d",&s,&b);
    for(int i=1;i<=s;i++){
        scanf("%d",&a[i]);
    }
    for(int i=1;i<=b;i++){
        scanf("%d%d",&ba[i].d,&ba[i].g);
        ba[i].id=i;
    }
    sort(ba+1,ba+b+1);
    for(int i=1;i<=b;i++){
        sum[i]=sum[i-1]+ba[i].g;
    }
    for(int i=1;i<=s;i++){
        printf("%lld%c",sum[bs(0,b,a[i])]," \n"[i==s]);
    }
    return 0;
}

CF1184 B2

CF1184 C1

暴力地找四个点,然后判断一下他们构成的矩形上是不是正好缺少一个点qwq

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#define MAXN 100010
using namespace std;
int n;
struct Node{int x,y;}node[MAXN];
inline void calc(int a,int b,int c,int d)
{
    int down=0x3f3f3f3f,up=0,ll=0x3f3f3f3f,rr=0,cnt=0;
    ll=min(ll,node[a].x),ll=min(ll,node[b].x),ll=min(ll,node[c].x),ll=min(ll,node[d].x);
    rr=max(rr,node[a].x),rr=max(rr,node[b].x),rr=max(rr,node[c].x),rr=max(rr,node[d].x);
    down=min(down,node[a].y),down=min(down,node[b].y),down=min(down,node[c].y),down=min(down,node[d].y);
    up=max(up,node[a].y),up=max(up,node[b].y),up=max(up,node[c].y),up=max(up,node[d].y);
    int kkk;
    for(int i=1;i<=n;i++)
    {
        if(ll<=node[i].x&&node[i].x<=rr&&(node[i].y==down||node[i].y==up)) cnt++;
        else if(down<=node[i].y&&node[i].y<=up&&(node[i].x==ll||node[i].x==rr)) cnt++;
        else kkk=i;
    }
    if(cnt==n-1)
    {
        printf("%d %d\n",node[kkk].x,node[kkk].y);
        exit(0);
    }
}
int main()
{
    #ifndef ONLINE_JUDGE
    freopen("ce.in","r",stdin);
    #endif
    scanf("%d",&n);
    for(int i=1;i<=4*n+1;i++)
    {
        scanf("%d%d",&node[i].x,&node[i].y);
    }
    n=4*n+1;
    for(int i=1;i<=n;i++)
        for(int j=i+1;j<=n;j++)
            for(int k=j+1;k<=n;k++)
                for(int p=k+1;p<=n;p++)
                    calc(i,j,k,p);
    return 0;
}

CF1184 C2

CF1184 D1

开始还以为要用链表直接模拟即可,注意判断一下加入和删除的位置和当前主人公所在位置的大小。


 #include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#define MAXN 100010
#define ll long long
using namespace std;
int n,m,k,t;
int main()
{
    #ifndef ONLINE_JUDGE
    freopen("ce.in","r",stdin);
    #endif
    scanf("%d%d%d%d",&n,&k,&m,&t);
    while(t--)
    {
        int op,pos;
        scanf("%d%d",&op,&pos);
        if(op==0)
        {
            if(pos>=k) n=pos;
            else n-=pos,k-=pos;
        }
        else
        {
            if(pos<=k) k++,n++;
            else n++;
        }
        printf("%d %d\n",n,k);
    }
    return 0;
}

CF1184 E1

二分一下桥1的值,看看能否在最小生成树中。

#include<bits/stdc++.h>

using namespace std;

const int N=1e6+6;

int n,m,fr[N],to[N],w[N],fa[N],siz[N];

bool usd[N];

int find(int u){
    return fa[u]==u?fa[u]:fa[u]=find(fa[u]);
}

struct edge{
    int u,v,w,id;
    bool operator<(const edge&rhs)const{
        return w<rhs.w;
    }
}e[N];

bool unifa(int u,int v){
    if(find(u)==find(v)){
        return 0;
    }
    fa[find(v)]=find(u);
    return 1;
}

bool can(int u){
    for(int i=1;i<=n;i++){
        fa[i]=i;
    }
    for(int i=2;i<=m;i++){
        if(e[i].w<u){
            unifa(e[i].u,e[i].v);
        }
    }
    return unifa(e[1].u,e[1].v);
}

int bs(int l,int r){
    if(l==r){
        return l;
    }
    int mid=(l+r+1)>>1;
    if(!can(mid)){
        return bs(l,mid-1);
    }
    else{
        return bs(mid,r);
    }
}

int main(){
    scanf("%d%d",&n,&m);
    for(int i=1;i<=m;i++){
        scanf("%d%d%d",&e[i].u,&e[i].v,&e[i].w);
        e[i].id=i;
    }
    printf("%d\n",bs(0,1e9));
    return 0;
}

CF1184 E2

我们先构建最小生成树,然后每次处理到一条不在最小生成树上的边的时候,倍增往上面找最小的一条边的值就行了。

#include<bits/stdc++.h>
#define pii pair<int,int>
#define mk make_pair
#define fi first
#define se second
#define debug printf("%d %s\n",__LINE__,__FUNCTION__)

using namespace std;

const int N=1e6+6;

int n,m,fa[N],dep[N];

vector<int>G[N],W[N];

bool vis[N];int ans[N];

int find(int u){
    return fa[u]==u?fa[u]:fa[u]=find(fa[u]);
}

bool unifa(int u,int v){
    if(find(u)==find(v)){
        return 0;
    }
    fa[find(v)]=find(u);
    return 1;
}

struct edge{
    int u,v,w,id;
    edge(int ru=0,int rv=0,int rw=0,int ri=0){
        u=ru;v=rv;w=rw;id=ri;
    }
    bool operator<(const edge&rhs)const{
        return w<rhs.w;
    }
}e[N];

void addedge(int u,int v,int w){
    G[u].push_back(v);W[u].push_back(w);
}

int jump[N][18],mx[N][18];

void dfs(int u,int fr){
    for(int i=0,v;i<(int)G[u].size();i++){
        v=G[u][i];
        if(v==fr){
            continue;
        }
        dep[v]=dep[u]+1;
        jump[v][0]=u;
        mx[v][0]=W[u][i];
        for(int j=1;j<18;j++){
            jump[v][j]=jump[jump[v][j-1]][j-1];
            mx[v][j]=max(mx[v][j-1],mx[jump[v][j-1]][j-1]);
        }
        dfs(v,u);
    }
}

pii lca(int u,int v){
    int rep=0;
    if(dep[u]<dep[v]){
        swap(u,v);
    }
    for(int i=17;~i;i--){
        if(dep[jump[u][i]]>=dep[v]){
            rep=max(mx[u][i],rep);
            u=jump[u][i];
        }
    }
    if(u==v){
        return mk(u,rep);
    }
    for(int i=17;~i;i--){
        if(jump[u][i]!=jump[v][i]){
            rep=max(rep,max(mx[u][i],mx[v][i]));
            u=jump[u][i];
            v=jump[v][i];
        }
    }
    rep=max(rep,max(mx[u][0],mx[v][0]));
    return mk(jump[u][0],rep);
}

int query(int u,int v){
    return lca(u,v).se;
}

int main(){
    scanf("%d%d",&n,&m);
    for(int i=1,u,v,w;i<=m;i++){
        scanf("%d%d%d",&u,&v,&w);
        e[i]=edge(u,v,w,i);
    }
    for(int i=1;i<=n;i++){
        fa[i]=i;
    }
    sort(e+1,e+m+1);
    for(int i=1;i<=m;i++){
        if(unifa(e[i].u,e[i].v)){
            vis[e[i].id]=1;
            addedge(e[i].u,e[i].v,e[i].w);
            addedge(e[i].v,e[i].u,e[i].w);
        }
    }
    dep[1]=1;dfs(1,0);
    for(int i=1;i<=m;i++){
        if(!vis[e[i].id]){
            ans[e[i].id]=query(e[i].u,e[i].v);
        }
    }
    for(int i=1;i<=m;i++){
        if(!vis[i]){
            printf("%d\n",ans[i]);
        }
    }
    return 0;
}

CF1184 E3

原文地址:https://www.cnblogs.com/fengxunling/p/11148850.html

时间: 2024-10-08 09:21:15

Helvetic Coding Contest 2019的相关文章

Helvetic Coding Contest 2019 差A3 C3 D2 X1 X2

Helvetic Coding Contest 2019 A2 题意:给一个长度为 n 的01序列 y.认为 k 合法当且仅当存在一个长度为 n 的01序列 x,使得 x 异或 x 循环右移 k 位的 01 串得到 y .问合法的 k 的个数. \(n \le 2*10^5\) key:找规律 考虑如何check一个 k 是否合法.那么对于所有的 i 和 i-k 在模 n 的意义下,如果 y 的第 i 位为 0 则二者必须不同,否则必须相同.这样可以用并查集判断是否合法.实际上是把相同的缩起来后

2016ACM/ICPC亚洲区青岛站 Coding Contest 费用流

目录 2016ACM/ICPC亚洲区青岛站 Coding Contest 费用流 题目描述 题意(博主的鬼畜翻译): 分析: 代码 2016ACM/ICPC亚洲区青岛站 Coding Contest 费用流 题目描述 题目描述 A coding contest will be held in this university, in a huge playground. The whole playground would be divided into N blocks, and there w

[AtCoder] NIKKEI Programming Contest 2019 (暂缺F)

[AtCoder] NIKKEI Programming Contest 2019 ??本来看见这一场的排名的画风比较正常就来补一下题,但是完全没有发现后两题的AC人数远少于我补的上一份AtCoder. A - Subscribers ??首先始终 \(max = \min(A, B)\) ,\(min\) 的话如果 \(A + B \leq N\) ,那么就是 \(0\) ,否则就是 \(A + B - N\) . int n, a, b; int main() { read(n), read

【AtCoder】Tenka1 Programmer Contest 2019

Tenka1 Programmer Contest 2019 C - Stones 题面大意:有一个01序列,改变一个位置上的值花费1,问变成没有0在1右边的序列花费最少多少 直接枚举前i个都变成0即可 #include <bits/stdc++.h> #define fi first #define se second #define pii pair<int,int> #define mp make_pair #define pb push_back #define space

[ICPC训练联盟周赛1] CTU Open Contest 2019

昨天ICPC训练联盟进行了第一场比赛,题目是CTU Open Contest 2019,烟台大学给出了解析. 题目和题解在此(提取码zre3) 我和索队还有yz组队,喊着队友nb就AK了,抱大腿真爽. A题是简单的组合数学,显然有公式 \(1\times C_n^1+2\times C_n^2+ \dots + n \times C_n^n=n \times 2^{n-1}\) 但忘了考虑\(n=0\)的情况,我wa了一发. B题题目我不太读得懂,yz A的. C题是算圆和矩形相交的面积,我抄了

2020-3-14 acm训练联盟周赛Preliminaries for Benelux Algorithm Programming Contest 2019 解题报告+补题报告

2020-3-15比赛解题报告+2020-3-8—2020-3-15的补题报告 2020-3-15比赛题解 训练联盟周赛Preliminaries for Benelux Algorithm Programming Contest 2019  A建筑(模拟) 耗时:3ms 244KB 建筑 你哥哥在最近的建筑问题突破大会上获得了一个奖项 并获得了千载难逢的重新设计城市中心的机会 他最喜欢的城市奈梅根.由于城市布局中最引人注目的部分是天际线, 你的兄弟已经开始为他想要北方和东方的天际线画一些想法

「CF1115」Microsoft Q# Coding Contest - Winter 2019 - Warmup

题目链接 资料 another 资料 赛后题解 被神仙 \(LMOliver\) 骗叫来一起做这套题被吊起来打. 毕竟量子计算什么的,只有神仙才会.我太蒻了. G1. AND oracle Intention 给你 \(N\) 个量子位,若全为 \(\left|1\right>\) (即逻辑与结果为 \(|1\rangle\)) 则翻转 \(y\) ,否则什么也不做. Solution 开始被这道题卡了好久. 只知道 X,H,CNOT,CCNOT 四个操作,硬是用这些操作搞出来了. 具体方法就是

AtCoder NIKKEI Programming Contest 2019 C. Different Strokes (贪心)

题目链接:https://nikkei2019-qual.contest.atcoder.jp/tasks/nikkei2019_qual_C 题意:给出 n 种食物,Takahashi 吃下获得 ai 快乐值,Aoki 吃下获得 bi 快乐值,两人轮流吃,他们的目标是最大化自己获得的快乐值减去她人获得的快乐值吗,问最后该值是多少. 题解:易知 Takahashi 要最大化答案而 Aoki 要最小化答案,考虑全部食物由 Aoki 吃下,则ans = -(b1 + b2 + .... + bn),

HDU 5988 Coding Contest(费用流+浮点数)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5988 题目大意: 给定n个点,m条有向边,每个点是一个吃饭的地方,每个人一盒饭.每个点有S个人,有B盒饭.每条边只能被走c次,每条边上都有电线,第一个人通过的时候,不会破坏电线,从第二个人开始,每次都有概率p破坏掉电线.使得每个人都能吃饭,求最小破坏电线的概率. 解题思路: 题目要求我们求最小破坏电线的概率,就是一个最小乘积问题,加上log可以将其转变为加法,那样就可以使用费用刘来解决了. 按以下方