打的第一场地区性比赛 全场划水卖萌出错误思路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. "); } } } } } }