zoukankan      html  css  js  c++  java
  • 2016东北赛补题记

    打的第一场地区性比赛 全场划水卖萌出错误思路QAQ

    于是半年之后终于开始补题...发现有两道场上没有想出来and场上没有de出bug的题 .. 都是水啊..?

    欣然补题 虽然因为小错误wa了一万遍

    HDU5927 

    就是统计一下有多少非重要点可以是两个重要点的lca

    因为其实重要点是很稠的 所以dfs序做一下处理 树状数组做一个维护区间和判断重要点个数 ( 虽然因为重要点太稠了 直接搜索也可以

    然后对每个非重要点 都看其儿子子树是否存在重要点 超过两个就可以被加入set

    需要注意的是因为进行了dfs序 节点有一套新的id来确保区间相连 所以类似树链剖分那样 更改都要用新id来

    #include<stdio.h>
    #include<string.h>
    #include<algorithm>
    #include<math.h>
    #include<map>
    #include<iostream>
    #include<string>
    #include<queue>
    #include<vector>
    using namespace std;
    #define L long long
    #define pb push_back
    vector<int >q[100050] ;
    vector<int >l[100050] ;
    vector<int >r[100050] ;
    int c[100050];
    int lowbit(int x){return (x&(-x)) ;}
    int n , m ;
    void add(int x,int val){
        while(x<=n){
            c[x]+=val ;
            x+=lowbit(x);
        }
    }
    int sum(int x){
        int val=0;
        while(x>0){
            val+=c[x];
            x-=lowbit(x);
        }
        return val;
    }
    int cnt ;
    int id[100050] ;
    void dfsx(int u,int pre){
        cnt++;
        id[u]=cnt;
        for(int i=0;i<q[u].size();i++){
            int v=q[u][i];
            if(v==pre)continue ;
            l[u].pb(cnt+1);
            dfsx(v,u);
            r[u].pb(cnt);
        }
        return ;
    }
    int b[100050] ;
    int main(){
        int t,cas=1;
        memset(c,0,sizeof(c));
        n=100000;
        for(int i=1;i<=100000;i++){
            add(i,1);
        }
        scanf("%d",&t);
        while(t--){
            scanf("%d%d",&n,&m) ;
            for(int i=1;i<=n;i++){
                q[i].clear();
                l[i].clear();
                r[i].clear();
            }
            for(int i=1;i<n;i++){
                int u,v;
                scanf("%d%d",&u,&v);
                q[u].pb(v);
                q[v].pb(u);
            }
            cnt = 0;
            dfsx(1,0) ;
            int num;
            printf("Case #%d:
    ",cas++);
            for(int i=1;i<=m;i++){
                scanf("%d",&num);
                for(int j=1;j<=num;j++)scanf("%d",&b[j]),add(id[b[j]],-1);
                int ans = n - num ;
                for(int j=1;j<=num;j++){
                    int u=b[j];
                    int tot=0;
                    for(int e=0;e<l[u].size();e++){
                        if(tot>=2)break;
                        int ll=l[u][e],rr=r[u][e];
                        if(sum(rr)-sum(ll-1)>0){
                            tot++;
                        }
                    }
                    if(tot>=2){
                        ans++;
                    }
                }
                for(int j=1;j<=num;j++){
                    add(id[b[j]],1);
                }
                printf("%d
    ",ans);
            }
        }
    }
    

    HDU5929

    观察到0+x=1 and x+0=1 所以建一个数组 存下所有的0的位置

    然后每次都寻找最靠近当前栈底的0 然后check 1 的奇偶

    如果当前只有一个0 或者没有x来使0变为1 ... 等等 都是需要很多很多check..

    可以使用双向队列来实现

    #include<stdio.h>
    #include<string.h>
    #include<algorithm>
    #include<math.h>
    #include<map>
    #include<iostream>
    #include<vector>
    #include<string>
    #include<queue>
    using namespace std;
    #define L long long
    #define pb push_back
    int a[800050] ;
    int fx;
    int l,r;
    int n ;
    int b[800050];
    int ll,rr;
    char op[10];
    int main(){
        int t,cas=1;
        scanf("%d",&t);
        while(t--){
            scanf("%d",&n);
            fx=0;
            ll=l=400000;
            rr=r=399999;
            printf("Case #%d:
    ",cas++);
            for(int tot=1;tot<=n;tot++){
                scanf("%s",op);
                if(op[2]=='S'){
                    int x;
                    scanf("%d",&x);
                    if(fx==0){
                        l--;
                        a[l]=x;
                        if(x==0){
                            ll--;
                            b[ll]=l;
                        }
                    }
                    else {
                        r++;
                        a[r]=x;
                        if(x==0){
                            rr++;
                            b[rr]=r;
                        }
                    }
                }
                else if(op[2]=='V'){
                    fx^=1;
                }
                else if(op[2]=='P'){
                    if(r-l+1>0){
                        if(fx==0){
                            l++;
                            if(rr-ll+1>0){
                                if(b[ll]==(l-1)){
                                    ll++;
                                }
                            }
                        }
                        else {
                            r--;
                            if(rr-ll+1>0){
                                if(b[rr]==(r+1)){
                                    rr--;
                                }
                            }
                        }
                    }
                    else printf("Invalid.
    ");
                }
                else {
                    if(fx==0){
                        if(r-l+1>0){
                            if(rr-ll+1>0){
                                if(r-l+1==1)printf("0
    ");
                                else {
                                    int siz = r - b[rr] + 1 ;
                                    if(l<b[rr]){
                                        if(siz%2==0)printf("0
    ");
                                        else printf("1
    ");
                                    }
                                    else {
                                        if(siz%2==1)printf("0
    ");
                                        else printf("1
    ");
                                    }
                                }
                            }
                            else {
                                int siz = r-l+1;
                                if(siz%2==0)printf("0
    ");
                                else printf("1
    ");
                            }
                        }
                        else {
                            printf("Invalid.
    ");
                        }
                    }
                    else {
                        if(r-l+1>0){
                            if(rr-ll+1>0){
                                if(r-l+1==1)printf("0
    ");
                                else {
                                    int siz = b[ll]-l+1;
                                    if(r>b[ll]){
                                        if(siz%2==0)printf("0
    ");
                                        else printf("1
    ");
                                    }
                                    else {
                                        if(siz%2==1)printf("0
    ");
                                        else printf("1
    ");
                                    }
                                }
                            }
                            else {
                                int siz = r-l+1;
                                if(siz%2==0)printf("0
    ");
                                else printf("1
    ");
                            }
                        }
                        else {
                            printf("Invalid.
    ");
                        }
                    }
                }
            }
        }
    }
    

      

  • 相关阅读:
    架构漫谈-阅读笔记(一)
    一线架构师实践指南--总结
    周四进度二
    质量属性改进
    结对作业第一次
    软件工程(2019)第三次作业
    软件工程(2019)第二次作业
    MarkDown编辑方法网址
    软件工程(2019年)第一次作业
    本人的coding地址
  • 原文地址:https://www.cnblogs.com/rayrayrainrain/p/6502873.html
Copyright © 2011-2022 走看看