10-3まとめ


第1題は再び点数を送って、残念ながら見ていないで、第3題を書いて行って、T 1は卵を爆発させます
第2題75分ネットストリームはとても書きやすいですが、私はまだ書いていません(厳密には問題を見ていません)
第3題は長い間木状の主席の木を書いて、それから各種のチェーン時計は木状の配列をプラスして、最後に木状の配列の主席の木を書きました
それから答案を出してから問題を読み間違えたことに気づいた==(こんなに複雑ではない)
//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
"::"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
",ans); } else { int ans=0; if(color[y]==false){printf("0
");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
",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分ロール太さ