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");
}
}
}
}
}
}
浙公网安备 33010602011771号