• Codeforces Round #679 Div.1


    幸亏没打。。。

    A

    从小到大排序,模拟。

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<cmath>
    #include<climits>
    #include<set>
    #define pii pair<int,int>
    #define fi first
    #define se second
    #define pb push_back
    #define mp make_pair
    using namespace std;
    inline int read(){
        int f=1,ans=0;char c=getchar();
        while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
        while(c>='0'&&c<='9'){ans=ans*10+c-'0';c=getchar();}
        return f*ans;
    }
    const int MAXN=1e5+11;
    int N,A[7],B[7][MAXN];
    multiset<int> s;
    void Ins(int w){/*cerr<<"Ins:"<<w<<endl;*/s.insert(w);return;}
    void Del(int w){/*cerr<<"Del:"<<w<<endl;*/s.erase(s.find(w));return;}
    int Qmax(){return *(--s.end());}
    struct Node{int w;pii p;}tmp[MAXN*7];
    bool cmp(Node x1,Node x2){return x1.w<x2.w;}
    int Ps[MAXN],Ans=INT_MAX,tot;
    int main(){
        //freopen("in2.txt","r",stdin);
        for(int i=1;i<=6;i++) A[i]=read();sort(A+1,A+7);
        N=read();    
        for(int i=1;i<=N;i++) {int x=read();for(int j=1;j<=6;j++) B[j][i]=x-A[j];}
        for(int i=1;i<=6;i++) for(int j=1;j<=N;j++){++tot;tmp[tot].w=B[i][j],tmp[tot].p=mp(i,j);}
        sort(tmp+1,tmp+tot+1,cmp);
        int ps=1;for(int i=1;i<=N;i++) Ins(B[6][i]),Ps[i]=6;bool ff=1;
        if(N==1){printf("%d
    ",0);return 0;}
        while(ps<=tot){
            int l=ps,r;for(r=ps;tmp[r].w==tmp[l].w;r++);r--;
            //cerr<<"l:"<<l<<" r:"<<r<<endl;
            for(int i=l;i<=r;i++) {
                Del(tmp[i].w),Ans=min(Ans,Qmax()-tmp[l].w),Ins(tmp[i].w);
                //cerr<<"res:"<<Qmax()-tmp[l].w<<endl;
                //if(Ans==-199) return 0;
            }
            for(int i=l;i<=r;i++){
                Del(tmp[i].w),Ps[tmp[i].p.se]--;if(!Ps[tmp[i].p.se]) ff=0;
                Ins(B[Ps[tmp[i].p.se]][tmp[i].p.se]);
            }if(!ff) break;
            ps=r+1;
        }
        printf("%d
    ",Ans);return 0;
    }
    View Code

    B

    构造。发现构造的是一个必要解,检验一下正确性。

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<cmath>
    #include<climits>
    #include<set>
    #define pii pair<int,int>
    #define fi first
    #define se second
    #define pb push_back
    #define mp make_pair
    using namespace std;
    inline int read(){
        int f=1,ans=0;char c=getchar();
        while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
        while(c>='0'&&c<='9'){ans=ans*10+c-'0';c=getchar();}
        return f*ans;
    }
    const int MAXN=2e5+11;
    char str[3];int N,sta[MAXN],Ans[MAXN],tot;
    set<int> s;
    void Ins(int w){s.insert(w);return;}
    void Del(int w){s.erase(s.find(w));return;}
    int Qmax(){return *(--s.end());}
    struct node{
        int opt,w;
    }tmp[MAXN];int cnt;
    int main(){
        //freopen("in1.txt","r",stdin);
        N=read();for(int i=1;i<=N;i++) Ins(i);
        for(int cas=1;cas<=2*N;cas++){
            scanf("%s",str+1);
            if(str[1]=='+'){tmp[++cnt].opt=0;sta[++sta[0]]=++tot;Ans[sta[sta[0]]]=Qmax();Del(Qmax());continue;}
            else{
                int x=read();
                tmp[++cnt].opt=1,tmp[cnt].w=x;
                if(!sta[0]){printf("NO
    ");return 0;}
                int ps=sta[sta[0]];
                if(Ans[ps]<x){printf("NO
    ");return 0;}
                if(Ans[ps]==x) {sta[0]--;continue;}
                Ins(Ans[ps]);sta[0]--;
                if(s.find(x)!=s.end()){Del(x);Ans[ps]=x;continue;}
                {printf("NO
    ");return 0;}
            }
        }
        s.clear();int ps=1;
        for(int i=1;i<=2*N;i++){
            if(!tmp[i].opt) {s.insert(Ans[ps]);ps++;continue;}
            else{
                int x=*s.begin();
                if(x!=tmp[i].w){printf("NO
    ");return 0;}
                s.erase(x);
            }
            
        }
        printf("YES
    ");
        for(int i=1;i<=N;i++) printf("%d ",Ans[i]);printf("
    ");
        return 0;
    }
     
    View Code

    C

     

    首先当 $a>bc$ 时显然答案为 $-1$ 。

    而我们只需要考虑在 $c$ 之前的,因为如果过期了那么还不如从后一段开始优。

    如图,记 $k=dfrac{a}{bd}$ ,则答案为 $a(k+1)-dfrac{k*(k+1)}{2}bd$。

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<cmath>
    #include<climits>
    #define pii pair<int,int>
    #define fi first
    #define se second
    #define pb push_back
    #define mp make_pair
    #define int long long
    using namespace std;
    inline int read(){
        int f=1,ans=0;char c=getchar();
        while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
        while(c>='0'&&c<='9'){ans=ans*10+c-'0';c=getchar();}
        return f*ans;
    }
    int A,B,C,D,T;
    signed main(){
        T=read();
        while(T--){
            A=read(),B=read(),C=read(),D=read();
            if(A>B*C){printf("-1
    ");continue;}
            if(C<=D){printf("%lld
    ",A);continue;}
            int K=A/(B*D);
            printf("%lld
    ",A*(K+1)-(1+K)*K/2*B*D);
        }return 0;
    }
    View Code

    D

    对于符合条件的最长链肯定有一个端点在直径的两个端点上。证明可以考虑相交部分奇偶讨论,可以发现直径一定优于其他。

    则直接将两个根摘出来,线段树维护即可。

    #include<iostream>
    #include<cstring>
    #include<cstdio>
    #include<cstring>
    #include<vector>
    #include<queue>
    #include<algorithm>
    #include<climits>
    #include<map>
    #define pii pair<int,int>
    #define pb push_back
    #define mp make_pair
    #define fi first
    #define se second
    using namespace std;
    inline int read(){
        int f=1,ans=0;char c=getchar();
        while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
        while(c>='0'&&c<='9'){ans=ans*10+c-'0';c=getchar();}
        return f*ans;
    }
    const int MAXN=5e5+11;
    int N;vector<pii> vec[MAXN];
    map<pii,int> M;
    struct Tree{
        int rt,siz[MAXN],dfn[MAXN],dis[MAXN],rev[MAXN],Id[MAXN],dep[MAXN];
        void dfs(int u,int fath){
            siz[u]=1;dfn[u]=++dfn[0];dep[u]=dep[fath]+1;rev[dfn[0]]=u;
            if(fath) Id[M[mp(u,fath)]]=u;
            for(auto pp:vec[u]){if(pp.fi!=fath){dis[pp.fi]=dis[u]+pp.se;dfs(pp.fi,u);siz[u]+=siz[pp.fi];}}
            return;
        }
        int Maxn[2][MAXN<<2],tag[MAXN<<2];
        void build(int k,int l,int r){
            if(l==r){Maxn[dis[rev[l]]&1][k]=dep[rev[l]];return;}
            int mid=(l+r)>>1;build(k<<1,l,mid),build(k<<1|1,mid+1,r);
            Maxn[0][k]=max(Maxn[0][k<<1],Maxn[0][k<<1|1]); Maxn[1][k]=max(Maxn[1][k<<1],Maxn[1][k<<1|1]);
            return;
        }
        void pushdown(int k){
            if(!tag[k]) return;
            if(!(tag[k]&1)){tag[k<<1]+=tag[k],tag[k<<1|1]+=tag[k];tag[k]=0;return;}
            swap(Maxn[0][k<<1],Maxn[1][k<<1]),swap(Maxn[0][k<<1|1],Maxn[1][k<<1|1]);
            tag[k<<1]+=tag[k],tag[k<<1|1]+=tag[k];tag[k]=0;return;
        }
        void Add(int k,int l,int r,int x,int y,int w){
            if(x<=l&&r<=y){tag[k]+=w;swap(Maxn[0][k],Maxn[1][k]);return;}
            pushdown(k);int mid=(l+r)>>1;
            if(x<=mid) Add(k<<1,l,mid,x,y,w); if(mid<y) Add(k<<1|1,mid+1,r,x,y,w);
            Maxn[0][k]=max(Maxn[0][k<<1],Maxn[0][k<<1|1]); Maxn[1][k]=max(Maxn[1][k<<1],Maxn[1][k<<1|1]);
            return;
        }
        int Qmax(){return Maxn[0][1];}
        void init(){memset(Maxn,-127/3,sizeof(Maxn)),memset(tag,0,sizeof(tag));dfs(rt,0);build(1,1,N);return;}
        void Add(int id){int u=Id[id];Add(1,1,N,dfn[u],dfn[u]+siz[u]-1,1);return;}
        void Del(int id){int u=Id[id];Add(1,1,N,dfn[u],dfn[u]+siz[u]-1,-1);return;}
        void print(){
            for(int i=1;i<=N;i++) printf("%d %d
    ",dis[i],rev[i]);printf("
    ");
            return;
        }
    }S1,S2;
    int dep[MAXN],rt1,rt2,Q,sta[MAXN];
    void dfs(int u,int fath){dep[u]=dep[fath]+1;for(auto pp:vec[u]) if(pp.fi!=fath) dfs(pp.fi,u);}
    int main(){
        //freopen("A.in","r",stdin);
        N=read();for(int i=1;i<N;i++){int u=read(),v=read(),w=read();sta[i]=w;M[mp(u,v)]=M[mp(v,u)]=i;vec[u].pb(mp(v,w)),vec[v].pb(mp(u,w));}
        dfs(1,0);int Max=1,ps=1;for(int i=2;i<=N;i++) if(dep[i]>Max) Max=dep[i],ps=i;
        rt1=ps;dfs(rt1,0);Max=1,ps=rt1;for(int i=1;i<=N;i++) if(dep[i]>Max) Max=dep[i],ps=i; rt2=ps;
        S1.rt=rt1,S2.rt=rt2;S1.init(),S2.init();
        //S1.print();
        //S1.print();return 0;
        Q=read();
        while(Q--){
            int x=read();
            //cerr<<sta[x]<<endl;
            if(!sta[x]){S1.Add(x),S2.Add(x);sta[x]^=1;}
            else if(sta[x]){S1.Del(x),S2.Del(x);sta[x]^=1;}
            int res1=S1.Qmax(),res2=S2.Qmax();
            printf("%d
    ",max(res1,res2)-1);
            //return 0;
        }return 0;
    }
    View Code
  • 相关阅读:
    TinyMail研究—Camellite的插件系统
    Dual Tone Multifrequency
    Linux PPP 数据收发流程
    这个五一怎么过?
    Linux下的磁盘加密方法
    udev的实现原理
    c语言中程序的循环控制,for语句。
    创建一个函数,将和有n个元素的数组中的key相等的所有元素的下标存储在另一数组中,并返回和key元素相同的元素的个数。
    c语言中数组元素的哨兵查找法
    c语言中数组,一般数组
  • 原文地址:https://www.cnblogs.com/si-rui-yang/p/13888043.html
Copyright © 2020-2023  润新知