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:\n",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\n",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:\n",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.\n");
            }
            else {
                if(fx==0){
                    if(r-l+1>0){
                        if(rr-ll+1>0){
                            if(r-l+1==1)printf("0\n");
                            else {
                                int siz = r - b[rr] + 1 ;
                                if(l<b[rr]){
                                    if(siz%2==0)printf("0\n");
                                    else printf("1\n");
                                }
                                else {
                                    if(siz%2==1)printf("0\n");
                                    else printf("1\n");
                                }
                            }
                        }
                        else {
                            int siz = r-l+1;
                            if(siz%2==0)printf("0\n");
                            else printf("1\n");
                        }
                    }
                    else {
                        printf("Invalid.\n");
                    }
                }
                else {
                    if(r-l+1>0){
                        if(rr-ll+1>0){
                            if(r-l+1==1)printf("0\n");
                            else {
                                int siz = b[ll]-l+1;
                                if(r>b[ll]){
                                    if(siz%2==0)printf("0\n");
                                    else printf("1\n");
                                }
                                else {
                                    if(siz%2==1)printf("0\n");
                                    else printf("1\n");
                                }
                            }
                        }
                        else {
                            int siz = r-l+1;
                            if(siz%2==0)printf("0\n");
                            else printf("1\n");
                        }
                    }
                    else {
                        printf("Invalid.\n");
                    }
                }
            }
        }
    }
}

  

posted @ 2017-03-04 21:59  天翎月  阅读(128)  评论(0编辑  收藏  举报