• Educational Codeforces Round 22


    Problems
     
     
    #Name  
    A
    standard input/output
    2 s, 256 MB
    Submit Add to favourites  x1629
    B
    standard input/output
    1 s, 256 MB
    Submit Add to favourites  x506
    C
    standard input/output
    1 s, 256 MB
    Submit Add to favourites  x656
    D
    standard input/output
    2 s, 256 MB
    Submit Add to favourites  x21
    E
    standard input/output
    2 s, 256 MB
    Submit Add to favourites  x92
    F
    standard input/output
    6 s, 256 MB
    Submit Add to favourites  x25

    A

    水题 不解释

    #include <bits/stdc++.h>
    using namespace std;
    int n,m,xx,yy,sum;
    int main(){
        scanf("%d",&n);
        for(int i=1;i<=n;i++)scanf("%d",&xx),sum+=xx;
        scanf("%d",&m);
        for(int i=1;i<=m;i++){
            scanf("%d%d",&xx,&yy);
            if(xx<=sum&&yy>=sum){printf("%d
    ",sum);return 0;}
            else if(sum<xx){printf("%d
    ",xx);return 0;}
        }puts("-1");
    }

    B

    这题全是细节

    要判有没有爆long long还有边界情况

    #include <bits/stdc++.h>
    using namespace std;
    #define int long long
    int x,y,l,r,ans;
    set<int>s;
    bool check(int x,int y){return log10(x)+log10(y)>18;}
    signed main(){
        scanf("%I64d%I64d%I64d%I64d",&x,&y,&l,&r);
        for(int i=0,t=1;;i++,t=t*x){
            if(t>r)break;
            for(int j=0,w=1;;j++,w=w*y){
                if(t+w>r)break;
                if(t+w>=l)s.insert(t+w);
                if(check(w,y))break;
            }
            if(check(t,x))break;
        }
        if(s.empty()){printf("%I64d
    ",r-l+1);return 0;}
        ans=max(*s.begin()-l,0ll);
        for(set<int>::iterator it=s.begin(),it2;it!=s.end();it++){
            it2=it;
            if(it!=s.begin())it2--;
            ans=max(ans,*it-*it2-1);
            it2=it,it2++;
            if(it2==s.end())ans=max(ans,r-*it);
        }printf("%I64d
    ",ans);
    }

    C

    贪心

    在不被追到的情况下走的最远

    一遍DFS即可  (为什么题解全是2遍dfs的  难以理解)

    //By SiriusRen
    #include <bits/stdc++.h>
    using namespace std;
    const int N=400050;
    int n,x,first[N],nxt[N],v[N],tot,deep[N],xx,yy,rec[N],fa[N],ans;
    void add(int x,int y){v[tot]=y,nxt[tot]=first[x],first[x]=tot++;}
    void dfs(int x){
        for(int i=first[x];~i;i=nxt[i])if(v[i]!=fa[x])
            fa[v[i]]=x,deep[v[i]]=deep[x]+1,dfs(v[i]),rec[x]=max(rec[x],rec[v[i]]+1);
    }
    int main(){
        memset(first,-1,sizeof(first));
        scanf("%d%d",&n,&x);
        for(int i=1;i<n;i++)scanf("%d%d",&xx,&yy),add(xx,yy),add(yy,xx);
        deep[1]=1,dfs(1);
        ans=max(ans,(deep[x]-1+rec[x])*2);
        for(int i=x,t=0;;i=fa[i],t++){
            if(deep[x]-t*2<2)break;
            ans=max(ans,(deep[i]-1)*2+rec[i]*2);
        }printf("%d
    ",ans);
    }

    D

    DP

    f[i][j] A选a[i] B选[j]的最长长度

    维护两个数组 X[i]表示mod 7 为i的最长长度

    Y[i]表示数字是i的最长长度

    为了去重

    只从i<j转移   更新i>j的情况

                if(i<j)ans=max(ans,f[j][i]=f[i][j]=max(max(Y[a[j]+1],max(Y[a[j]-1],X[a[j]%7])),f[i][0])+1);
                X[a[j]%7]=max(X[a[j]%7],f[i][j]),Y[a[j]]=max(Y[a[j]],f[i][j]);
    //By SiriusRen
    #include <bits/stdc++.h>
    using namespace std;
    const int N=5050;
    int f[N][N],a[N],n,X[7],Y[100500],ans;
    int main(){
        scanf("%d",&n);
        for(int i=1;i<=n;i++)scanf("%d",&a[i]);
        for(int i=0;i<=n;i++){
            memset(X,0,sizeof(X)),memset(Y,0,sizeof(Y));
            for(int j=1;j<=n;j++){
                if(i==j)continue;
                if(i<j)ans=max(ans,f[j][i]=f[i][j]=max(max(Y[a[j]+1],max(Y[a[j]-1],X[a[j]%7])),f[i][0])+1);
                X[a[j]%7]=max(X[a[j]%7],f[i][j]),Y[a[j]]=max(Y[a[j]],f[i][j]);
            }
        }
        printf("%d
    ",ans);
    }

    E

    一个点有没有被算到答案里  

    只跟它k次之前出现的地方有没有小于l有关

    那  主席树直接上

    //By SiriusRen
    #include <bits/stdc++.h>
    using namespace std;
    const int N=100050;
    vector<int>vec[N];
    int n,k,q,xx,yy,a[N],jy,s[N],lson[N*66],rson[N*66],tree[N*66],cnt,root[N],lst;
    void insert(int l,int r,int &pos,int last,int wei){
        pos=++cnt;tree[pos]=tree[last]+1;
        if(l==r)return;
        int mid=(l+r)>>1;
        if(mid<wei)lson[pos]=lson[last],insert(mid+1,r,rson[pos],rson[last],wei);
        else rson[pos]=rson[last],insert(l,mid,lson[pos],lson[last],wei);
    }
    int query(int l,int r,int pos,int last,int L,int R){
        if(l>=L&&r<=R)return tree[pos]-tree[last];
        int mid=(l+r)>>1;
        if(mid<L)return query(mid+1,r,rson[pos],rson[last],L,R);
        else if(mid>=R)return query(l,mid,lson[pos],lson[last],L,R);
        else return query(l,mid,lson[pos],lson[last],L,R)+query(mid+1,r,rson[pos],rson[last],L,R);
    }
    int main(){
        scanf("%d%d",&n,&k);
        for(int i=1;i<=n;i++){
            scanf("%d",&a[i]);
            vec[a[i]].push_back(i),jy=vec[a[i]].size()-1;
            s[i]=jy>=k?vec[a[i]][jy-k]:0,insert(0,N,root[i],root[i-1],s[i]);
        }
        scanf("%d",&q);
        while(q--){
            scanf("%d%d",&xx,&yy),xx=(xx+lst)%n+1,yy=(yy+lst)%n+1;
            if(xx>yy)swap(xx,yy);
            printf("%d
    ",lst=query(0,N,root[yy],root[xx-1],0,xx-1));
        }
    }

    F

    BZOJ 4025

    并查集+cdq分治

    我打的是线段树+vector

    最后DFS一遍

    效果一样

    //By SiriusRen
    #include <bits/stdc++.h>
    using namespace std;
    const int N=100050;
    int n,q,f[N],top,size[N],dis[N];
    struct Edge{int from,to,tim;Edge(){}Edge(int x,int y){from=x,to=y;}}edge[N];
    struct Update{int fx,fy,disx;Update(){}Update(int x,int y,int z){fx=x,fy=y,disx=z;}}upd[N];
    bool operator<(Edge a,Edge b){if(a.from!=b.from)return a.from<b.from;return a.to<b.to;}
    set<Edge>st;set<Edge>::iterator it;vector<Edge>vec[N*8];
    void insert(int l,int r,int pos,int L,int R,Edge t){
        if(l>=L&&r<=R){vec[pos].push_back(t);return;}
        int mid=(l+r)>>1,lson=pos<<1,rson=pos<<1|1;
        if(mid<L)insert(mid+1,r,rson,L,R,t);
        else if(mid>=R)insert(l,mid,lson,L,R,t);
        else insert(l,mid,lson,L,R,t),insert(mid+1,r,rson,L,R,t);
    }
    int find(int x){return x==f[x]?x:find(f[x]);}
    void merge(int x,int y,int z){
        if(size[x]>size[y])swap(x,y);
        upd[++top]=Update(x,y,dis[x]);
        f[x]=y,dis[x]=z,size[y]+=size[x];
    }
    bool get_dis(int x){
        int r=0;
        while(f[x]!=x)r^=dis[x],x=f[x];
        return r;
    }
    void query(int l,int r,int pos){
        int rec=top;
        for(int i=0;i<vec[pos].size();i++){
            int x=find(vec[pos][i].from),y=find(vec[pos][i].to),z=get_dis(vec[pos][i].from)^get_dis(vec[pos][i].to)^1;
            if(x!=y)merge(x,y,z);
            else if(z&1){for(int j=l;j<=r;j++)puts("NO");goto ed;}
        }
        if(l==r)puts("YES");
        else query(l,(l+r)>>1,pos<<1),query((l+r)/2+1,r,pos<<1|1);
        ed:for(int i=top;i>rec;i--){
            int fx=upd[i].fx,fy=upd[i].fy;
            dis[fx]=0,f[fx]=fx,size[fy]-=size[fx];
        }top=rec;
    }
    int main(){
        scanf("%d%d",&n,&q);
        for(int i=1;i<=n;i++)f[i]=i;
        for(int i=1;i<=q;i++){
            scanf("%d%d",&edge[i].from,&edge[i].to);edge[i].tim=i;
            if((it=st.find(edge[i]))==st.end())st.insert(edge[i]);
            else insert(1,q,1,it->tim,i-1,edge[i]),st.erase(it);
        }
        for(it=st.begin();it!=st.end();it++)insert(1,q,1,it->tim,q,*it);
        query(1,q,1);
    }
  • 相关阅读:
    禁止用户选中页面
    冒泡排序
    hadoop-1.2.1安装配置
    CentOS碰到两个问题,顺便解决了下
    CentOS 安装
    VM配置一个待安装LUNIX系统的环境
    CentOS下IP的配置
    C++ Win系统下的调试
    题解 P1781 【宇宙总统】
    题解 P2089 【烤鸡】
  • 原文地址:https://www.cnblogs.com/SiriusRen/p/7075039.html
Copyright © 2020-2023  润新知