第一题再次送分,可惜没看见,写第三题去了,T1爆蛋
第二题75分网络流特别好写,但是我还是没写(严格来说题都没看)
第三题写了好久树状主席树,然后各种链表加树状数组,最后写了个树状数组套主席树
然后交卷完发现题读错了= =(哪有这么复杂)
//Copyright(c)2015 liuchenrui #include<cstdio> #include<ctime> #include<iostream> #include<algorithm> #include<cstring> #include<queue> #define N 100010 #define rep(i,j) for(int i=1;i<=j;i++) #define foreach(u,v) for(int u=first[v];u;u=edge[u].next) using namespace std; inline void R(int &v) { v=0;char c=0;int p=1; while(c<'0' || c>'9'){if(c=='-')p=-1;c=getchar();} while(c>='0' && c<='9'){v=(v<<3)+(v<<1)+c-'0';c=getchar();} v*=p; } int dfsxu[N],tot; int father[N]; int ask[N]; int n,q; int jump[N][18]; int deep[N]; struct Edge { int to,next,from; }edge[2*N],e[2*N]; int first[N],size,root; int f[N],S; bool color[N]; int sub[N],prev[N],next[N]; int num[N]; priority_queue< pair<int,int> >que[N]; void addedge(int x,int y) { size++; edge[size].to=y; edge[size].next=first[x]; first[x]=size; } void Addedge(int x,int y) { S++; e[S].to=y; e[S].from=x; e[S].next=f[x]; f[x]=S; } void get_dfs(int now) { foreach(u,now)if(edge[u].to!=father[now])get_dfs(edge[u].to); dfsxu[++tot]=now;sub[now]=tot; } void dfs(int now) { jump[now][0]=father[now]; deep[now]=deep[father[now]]+1; rep(i,17)jump[now][i]=jump[jump[now][i-1]][i-1]; foreach(u,now)if(edge[u].to!=father[now])dfs(edge[u].to); } void num_dfs(int now) { num[now]=min(num[now],now); for(int u=f[now];u;u=e[u].next) { if(e[u].to!=father[now]) { num_dfs(e[u].to); num[now]=min(num[now],num[e[u].to]); } } } int flag1=0,flag2=0; int num_2,t; int begin=1; int Tree[N]; #define lowbit(i) ((i)&(-(i))) void add(int x,int val) { for(int i=x;i<N;i+=lowbit(i)) Tree[i]+=val; } int get(int x) { int sum=0; for(int i=x;i;i-=lowbit(i))sum+=Tree[i]; return sum; } int main() { int _q=10<<20; char *_p=(char*)malloc(_q)+_q; __asm__("movl %0, %%esp\n"::"r"(_p)); freopen("ball.in","r",stdin); freopen("ball.out","w",stdout); memset(num,127,sizeof num); R(n);R(q); rep(i,n) { R(father[i]); if(father[i]==0)root=i; //else que[i].push(father[i]),que[father[i]].push(i); else { Addedge(i,father[i]); Addedge(father[i],i); } } num_dfs(root); rep(i,S) { que[e[i].to].push(make_pair(num[e[i].from],e[i].from)); } rep(i,n) { while(!que[i].empty()) addedge(i,que[i].top().second),que[i].pop(); } rep(i,n)prev[i]=i-1,next[i]=i+1,add(i,1); get_dfs(root);dfs(root); rep(T,q) { int x,y;R(x),R(y); if(x==1) { int ans; while(y--) { add(begin,-1); color[dfsxu[begin]]=true; ans=dfsxu[begin]; begin=next[begin]; prev[begin]=0; } printf("%d\n",ans); } else { int ans=0; if(color[y]==false){printf("0\n");continue;} for(int i=17;i>=0;i--) { if(color[jump[y][i]]==true)y=jump[y][i],ans+=(1<<i); } color[y]=false; add(sub[y],1); printf("%d\n",ans); if(begin>sub[y]) { prev[begin]=sub[y]; next[sub[y]]=begin; begin=sub[y]; continue; } int l=1,r=sub[y]; int w=get(sub[y]); if(get(l)==w-1)r=l; else { while(l<r) { int mid=l+r>>1; if(get(mid)>=w-1)r=mid; else l=mid+1; } r=l; } next[sub[y]]=next[r]; next[r]=sub[y]; } } }
15分滚粗