• Codeforces Round #200 (Div. 1) BCD


    为了锻炼个人能力奋力div1 为了不做原题从200开始

    B 两个电线缠在一起了 能不能抓住两头一扯就给扯分开

    很明显当len为odd的时候无解 当len为偶数的时候 可以任选一段长度为even的相同字符串给它翻过去 即 ++--++++--++ -> ++--------++ -> ++++++++++++ 

    一直这样下去一定可以翻出结果 但是复杂度很高 不能暴力的去找

    考虑用一个栈 依次往里放 每次看到top等于当前的这个字符 意义是当前有一个偶数了  便pop出来 最后判断栈的empty

    做完B的我十分欣慰 感觉这样练下去应该提升真的不小

    C 磁盘调度算法 读取不花时间 n个磁头 m个地点 划过就算读入了 可以多个磁头一起随便移动 问最少多少时间所有的地点都能被划过

    最小化最大值问题 考虑二分一下maxtime 然后枚举磁头来check 对于当前剩余的地点序列 我这个磁头从左到右最远可以读到哪儿

    就是做一个类似于双指针的check 磁头的指针后跳 那么地点的指针可能也往后跳 看看最后地点的指针有没有跳完

    #include<stdio.h>
    #include<math.h>
    #include<string.h>
    #include<vector>
    #include<queue>
    #include<map>
    #include<iostream>
    #include<algorithm>
    #include<stack>
    using namespace std;
    #define L long long
    #define pb push_back
    #define ph push
    #define lala printf(" --------- 
    ") ;
    #define rep(i, a, b) for (L i=a;i<=b;++i)
    #define dow(i, b, a) for (L i=b;i>=a;--i)
    #define fmt(i,n) if(i==n)printf("
    ");else printf(" ") ;
    #define lro ro*2
    #define rro ro*2+1
    #define fi first
    #define se second
    template<class T> inline void flc(T &A, L x){memset(A, x, sizeof(A));}
    L read(){L x=0,f=1;char ch=getchar();while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}return x*f;}
    L n , m ;
    L a[100050] ;
    L b[100050] ;
    
    bool check(L time) {
        L last = 1 ;
        rep(i,1,n){
            if(b[last] <= a[i]) {
                L xd = a[i] - b[last] ;
                if(time < xd) {
                    return false ;
                }
                L yy = (time - xd) / 2 ;
                L where1 = a[i] + yy ;
    
                L xd2 = time - (a[i] - b[last]) ;
                L where2 = (xd2 + b[last]) ;
                L where = max(where1 , where2) ;
                while(b[last] <= where) {
                    last ++ ;
                }
                if(last > m) return true ;
            }
            else {
                L where = a[i] + time ;
                while(b[last] <= where) {
                    last ++ ;
                }
                if(last > m) return true ;
            }
        }
        return false ;
    }
    
    int main () {
        n = read() ;
        m = read() ;
        rep(i,1,n) a[i] = read() ;
        rep(i,1,m) b[i] = read() ;
        L l = 0 ;
        L r = 30000000000 ;
        L res = 0 ;
        while(l <= r) {
            L mid = (l + r) / 2 ;
            if(check(mid)) {
                r = mid - 1 ;
                res = mid ;
            }
            else {
                l = mid + 1 ;
            }
        }
        printf("%I64d
    " , res) ;
    }
    

    写完C1A了..asuka一脸迷茫 这个C明显比B简单的样子...那个年代的cf有点奇怪的说...

    虽然开专题准备做div1BC 但是注意到D好像比C过的还多 于是做一下D

    D 一个树 3个操作 op1 把一个点和他的子树群体置1  op2 把一个点和他的直系先辈群体置0  op3 查询一个点的值

    dfs序标一下号 建立两个线段树来维护op1和op2

    op1 线段树区间更新单点查询 由于val递增 其实不需要lazy标记

    op2 线段树单点更新区间维护最大值 查询的意义是一个点的子树区间内谁最后被op2了

    op3 对两个线段树询问 比一下谁最大

    可能..做久远一点的CF idea都被用惯了 可能还是在做原题啊...

    #include<stdio.h>
    #include<math.h>
    #include<string.h>
    #include<vector>
    #include<queue>
    #include<map>
    #include<iostream>
    #include<algorithm>
    #include<stack>
    using namespace std;
    #define L long long
    #define pb push_back
    #define ph push
    #define lala printf(" --------- 
    ") ;
    #define rep(i, a, b) for (int i=a;i<=b;++i)
    #define dow(i, b, a) for (int i=b;i>=a;--i)
    #define fmt(i,n) if(i==n)printf("
    ");else printf(" ") ;
    #define lro ro*2
    #define rro ro*2+1
    #define fi first
    #define se second
    template<class T> inline void flc(T &A, int x){memset(A, x, sizeof(A));}
    int read(){int x=0,f=1;char ch=getchar();while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}return x*f;}
    
    int n , qnum ;
    vector<int>q[500050] ;
    int cnt ;
    int l[500050] , r[500050] ;
    int id[500050] ;
    void dfs(int u , int fa) {
        cnt ++ ;
        l[u] = cnt ;
        int siz = q[u].size() ;
        rep(i,0,siz-1){
            int v = q[u][i] ;
            if(v==fa)continue ;
            dfs(v,u) ;
        }
        r[u] = cnt ;
    }
    int last[500000 * 4] ;
    int last2[500000 * 4] ;
    /// ---  op 1
    void build() {
        flc(last,0);
        flc(last2,0);
    }
    int ans1 ;
    void query(int ro,int l,int r,int pos) {
        ans1 = max(ans1,last[ro]);
        int mid=(l+r)/2;
        if(l==r)return ;
        if(pos<=mid)query(lro,l,mid,pos);
        else query(rro,mid+1,r,pos);
    }
    void upda(int ro,int l,int r,int ul,int ur,int val) {
        if(l>=ul&&r<=ur){
            last[ro]=val;
            return;
        }
        int mid=(l+r)/2;
        if(ul<=mid)upda(lro,l,mid,ul,ur,val);
        if(ur>=mid+1)upda(rro,mid+1,r,ul,ur,val);
    }
    /// --- op 2
    int query2(int ro,int l,int r,int ul,int ur) {
        if(l>=ul&&r<=ur){
            return last2[ro];
        }
        int ans=0;
        int mid=(l+r)/2;
        if(ul<=mid) ans = max(ans,query2(lro,l,mid,ul,ur)) ;
        if(ur>mid) ans = max(ans , query2(rro,mid+1,r,ul,ur)) ;
        return ans ;
    }
    void upda(int ro,int l,int r,int pos,int val) {
        if(l==r) {
            last2[ro] = val ;
            return ;
        }
        int mid=(l+r)/2;
        if(pos<=mid) upda(lro,l,mid,pos,val);
        else upda(rro,mid+1,r,pos,val);
        last2[ro]=max(last2[lro],last2[rro]) ;
    }
    /// --- op 3
    
    int solve(int x) {
        ans1 = 0 ;
        query(1,1,n,l[x]) ;
        int ans2 = query2(1,1,n,l[x],r[x]) ;
        if(ans1 == 0 && ans2 == 0) {
            printf("0
    ") ;
        }
        else {
            if(ans1 > ans2) printf("1
    ") ;
            else printf("0
    ") ;
        }
    }
    
    
    int main () {
        n = read();
        rep(i,1,n) q[i].clear() ;
        rep(i,1,n-1) {
            int u=read();
            int v=read() ;
            q[u].pb(v);
            q[v].pb(u);
        }
        cnt = 0 ;
        dfs(1,-1) ;
        build() ;
        qnum = read();
        rep(i,1,qnum) {
            int op = read() ;
            int x = read() ;
            if(op == 1) {
                upda(1,1,n,l[x],r[x],i) ;
            }
            else if(op == 2) {
                upda(1,1,n,l[x],i) ;
            }
            else {
                solve(x) ;
            }
        }
    }
    
  • 相关阅读:
    1相关介绍
    json c++处理学习
    重定向问题学习
    unordered_multimap学习
    std::bind()功能学习
    grep命令学习
    gdb调试coredump学习
    系统过载理解
    C++中int8_t int16_t、int32_t、int64_t、uint8_t等学习
    awk命令学习
  • 原文地址:https://www.cnblogs.com/rayrayrainrain/p/7445221.html
Copyright © 2020-2023  润新知