Educational Codeforces Round 58 (Rated for Div. 2)

Posted mountaink

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Educational Codeforces Round 58 (Rated for Div. 2)相关的知识,希望对你有一定的参考价值。

A. Minimum Integer

技术图片
#include<bits/stdc++.h>
#define clr(a,b) memset(a,b,sizeof(a))
using namespace std;
typedef long long ll; 
const int maxn=1e3+10;
struct node{
    ll num,mag;
    friend bool operator <(const node &a,const node &b){
        return a.mag>b.mag;
    }
}a[maxn];
int n;
ll p[70];
ll add(ll x,ll val){
    for(int i=60;i>=0;i--)
    {
        if(x&(1<<i))
        {
            if(!p[i]){
                p[i]=x;
                break;
            }else{
                x=x^p[i];
            }
        }
    }
    if(x>0)return val;
    return 0;
}
int main(){
    while(cin>>n)
    {
        ll l,r,d;
        while(n--)
        {
            cin>>l>>r>>d;
            if(d<l)printf("%lld
",d);
            else{
                printf("%lld
",(r/d+1)*d);
                
            }
        }
    }
}
View Code

 

B. Accordion

小模拟,从前往后扫到第一个 [: ,从后往前扫到第一个 :] ,然后数中间的 “|” 就可以了。

技术图片
#include<bits/stdc++.h>
#define clr(a,b) memset(a,b,sizeof(a))
using namespace std;
typedef long long ll; 
const int maxn=5e5+10;
char s[maxn];
int main(){
    while(scanf("%s",s+1)!=EOF)
    {
        int flag=0,p1=-1,p2=-1,len=strlen(s+1);
        for(int i=1;i<=len;i++)
        {
            if(flag==0)
            {
                if(s[i]==[)flag=1;
            }else{
                if(s[i]==:){
                    p1=i;
                    break;
                }
            }
        }
        flag=0;
        for(int i=len;i>p1&&i>0;i--)
        {
            if(flag==0)
            {
                if(s[i]==])flag=1;
            }else{
                if(s[i]==:){
                    p2=i;
                    break;
                }
            }
        }
        if(p1==-1||p2==-1){
            printf("-1
");
            continue;
        }
        int tot=0;
        for(int i=p1+1;i<p2;i++)
        {
            if(s[i]==|)tot++;
        }
        printf("%d
",tot+4);
    }
}
View Code

 

C. Division and Union

题意:把给出的区间分成两部分,使不同部分的区间,不会有交点。

按 l 排序一遍,如果 l 小于前面最大的 r ,则必须和前面分在同一个群,否则就到第二个群。

技术图片
#include<bits/stdc++.h>
#define clr(a,b) memset(a,b,sizeof(a))
using namespace std;
typedef long long ll; 
const int maxn=2e5+10;
int T,n;
struct node{
    int l,r;
    int id;
    friend bool operator <(const node &a,const node &b)
    {
        return a.l<b.l;
    }
}a[maxn]; 
int ans[maxn];
int main(){
    cin>>T;
    while(T--)
    {
        cin>>n;
        for(int i=1;i<=n;i++)
        {
            scanf("%d%d",&a[i].l,&a[i].r);
            a[i].id=i;
        }
        sort(a+1,a+1+n);
        int maxx=a[1].r,tep=0,flag=0;
        ans[a[1].id]=1;
        for(int i=2;i<=n;i++)
        {
            if(a[i].l<=maxx){
                ans[a[i].id]=1+tep;
            }else{
                ans[a[i].id]=1+1-tep;
                tep=1-tep;
                flag=1;
            }
            maxx=max(maxx,a[i].r);
            
        }
        if(flag==0)puts("-1");
        else{
            for(int i=1;i<=n;i++)
            {
                printf("%d%c",ans[i]," 
"[i==n]);
            }
        }
    }
}
View Code

 

D. GCD Counting

题意:给出一颗点带权的数,求任意两点简单路径上的点gcd大于1的长度最大是多少。

题解:

     gcd大于1即不互质,若一条路径是合法路径,则必定有一个大于1的公共质因子。所以我们可以对每个小于2e5的质数重新建树,然后再求树的直径。

       建图是怎么建的呢,其实只要把边读入的时候,就把边塞到各自的质因子背包里面去,最后把每个背包的边都建立出来,跑树上直径。

  但是有一个问题是,小于2e5的质数有一万多个,树的直径又是O(n)的,这样看上去会超时,我也困扰了好久。其实,两个点之间的公共gcd的质因子个数最多就十个左右,(再多就爆了)也就意味着每个点最多被建图十次,所以如果跑树的直径最后的总计算次数也就是10*O(n)左右,不会超时,这类问题以后要注意,明明很快就想到标算的,但迟迟不敢动手。

技术图片
#include<bits/stdc++.h>
#define clr(a,b) memset(a,b,sizeof(a))
using namespace std;
typedef long long ll; 
const int maxn=2e5+10;
int prim[maxn],n,u,v,a[maxn];
int gcd(int a,int b){
    return b==0?a:gcd(b,a%b);
}
void initPrim(){
    for(int i=2;i<=2e5/2;i++)
    {
        for(int j=2;i*j<=2e5;j++)
        {
            prim[i*j]=1;
        }
    }
}
struct edge{
    int u,v;
};
vector<edge>ve[maxn];
vector<int >e[maxn];
vector<int >jont;
bool vis[maxn];
int ans=0;
int dfs(int u,int fa,int dep){
    vis[u]=1;
    int f=0;
    int flink=0,slink=0;
    for(int i=0;i<e[u].size();i++)
    {
        int v=e[u][i];
        if(v==fa)continue;
        f=1;
        int tep=dfs(v,u,dep+1);
        if(tep>flink)slink=flink,flink=tep;
        else if(tep>slink)slink=tep;
    }
    ans=max(ans,max(dep+flink,flink+1+slink));
    return flink+1;
    
}
int main(){
    initPrim();
    while(cin>>n)
    {
        ans=1;
        int fff=0;
        for(int i=1;i<=n;i++)
        {
            scanf("%d",&a[i]);
            if(a[i]>1)fff=1;
        }
        for(int i=2;i<=2e5;i++)ve[i].clear();
        for(int i=1;i<n;i++)
        {
            scanf("%d%d",&u,&v);
            int k=gcd(a[u],a[v]);
            if(k>1){
                for(int j=1;j*j<=k;j++)
                {
                    if(k%j==0)
                    {
                        if(j!=1&&prim[j]==0)    ve[j].push_back({u,v});
                        if(j*j!=k&&prim[k/j]==0) ve[k/j].push_back({u,v});
                    }
                }
            }
        }
        if(fff==0){
            puts("0");
            continue;
        }
        clr(vis,1);
        for(int i=2;i<=2e5;i++)
        {
            if(!prim[i])
            {
                for(int j=0;j<ve[i].size();j++)
                {
                    if(vis[ve[i][j].u]==1)
                    {
                        jont.push_back(ve[i][j].u);
                    }
                    if(vis[ve[i][j].v]==1)
                    {
                        jont.push_back(ve[i][j].v);
                    }
                    vis[ve[i][j].u]=0;
                    vis[ve[i][j].v]=0;
                    e[ve[i][j].u].push_back(ve[i][j].v);
                    e[ve[i][j].v].push_back(ve[i][j].u);
                }
                for(int j=0;j<jont.size();j++)
                {
                    vis[jont[j]]=0;
                }
                for(int j=0;j<jont.size();j++)
                {
                    int u=jont[j];
                    if(!vis[u]){
                        dfs(u,0,1);
                    }
                }
                for(int j=0;j<jont.size();j++)
                {
                    e[jont[j]].clear();
                }
                jont.clear();
            }
        }
        cout<<ans<<endl;
    }
}
View Code

 

E. Polycarp‘s New Job

为什么这会是E题,一开始我以为是求有几张钞票能被塞进去,看了样例才发现我想太多了。

反正就钞票放进去的时候,固定格式,短的一边在下面,钱包也是这样,分别记录长边和短边的最大值,比一下即可。

技术图片
#include<bits/stdc++.h>
#define clr(a,b) memset(a,b,sizeof(a))
using namespace std;
typedef long long ll; 
const int maxn=2e5+10;
int T,n;
struct node{
    int l,r;
    int id;
    friend bool operator <(const node &a,const node &b)
    {
        return a.l<b.l;
    }
}a[maxn]; 
int ans[maxn];
int main(){
    cin>>T;
    int maxl=0,maxr=0,l,r;
    char op[3];
    while(T--)
    {
        scanf("%s%d%d",op,&l,&r);
        if(op[0]==+){
            if(l>r)swap(l,r);
            maxl=max(maxl,l),maxr=max(maxr,r);
        }else{
            if(l>r)swap(l,r);
            if(l>=maxl&&r>=maxr)printf("YES
");
            else puts("NO");
        }
    }
}
View Code

 

以上是关于Educational Codeforces Round 58 (Rated for Div. 2)的主要内容,如果未能解决你的问题,请参考以下文章

Educational Codeforces Round 7 A

Educational Codeforces Round 7

Educational Codeforces Round 90

Educational Codeforces Round 33

Codeforces Educational Codeforces Round 54 题解

Educational Codeforces Round 27