151228 BJOI2015 总结

T1

链剖+树套树

脸黑+常数大。。。50滚粗了

然而BZOJ能A

T2

把每棵树复制50次,然后暴力搞

结果自己写的哈希有冲突。。。下来发现简直哭死

T3

dp有40

正解就是组合数模数搞一搞。。。

//Copyright(c)2015 liuchenrui
#include<cstdio>
#include<ctime>
#include<iostream>
#include<algorithm>
#include<cstring>
#include<set>
//#define mp make_pair
//#define pii pair<int,int>
#define N 100010
#define M 10000010
#define A 1001
using namespace std;
inline void splay(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;
}
struct Edge{
	int to,next;
}edge[N<<2];
struct pii{
	int first,second;
	inline bool operator < (const pii &b)const{
		if(first!=b.first)return first<b.first;
		return second<b.second;
	}
};
#define mp(a,b) (pii){a,b}
int live[N],atk[N];
int sub[N],root[N],top[N],deep[N],size[N];
int Size,first[N],fa[N];
int n,m,q,k;
int ans[55],tt,tot,sum,cnt;
set< pii >t[N<<3];
int ma[N<<3];
void addedge(int x,int y){
	Size++;
	edge[Size].to=y;
	edge[Size].next=first[x];
	first[x]=Size;
}
void dfs(int now,int F){
	deep[now]=deep[F]+1;size[now]=1;fa[now]=F;
	for(int u=first[now];u;u=edge[u].next){
		if(edge[u].to!=F){
			dfs(edge[u].to,now);
			size[now]+=size[edge[u].to];
		}
	}
}
void dfs(int now,int fa,bool is){
	sub[now]=++tot;
	top[now]=is?top[fa]:now;int a=0,b=0;
	for(int u=first[now];u;u=edge[u].next){
		if(size[edge[u].to]>b&&edge[u].to!=fa){
			a=edge[u].to,b=size[edge[u].to];
		}
	}
	if(!a)return;dfs(a,now,1);
	for(int u=first[now];u;u=edge[u].next){
		if(edge[u].to!=fa&&edge[u].to!=a){
			dfs(edge[u].to,now,0);
		}
	}
}
void insert(int l,int r,int w,int who){
	t[w].insert(mp(atk[who],who));
	if(l==r)return;int mid=l+r>>1;
	if(sub[live[who]]<=mid)insert(l,mid,w<<1,who);
	else insert(mid+1,r,w<<1|1,who);
}
void erase(int l,int r,int w,int who){
	t[w].erase(mp(atk[who],who));
	if(l==r)return;int mid=l+r>>1;
	if(sub[live[who]]<=mid)erase(l,mid,w<<1,who);
	else erase(mid+1,r,w<<1|1,who);
}
void insert(int who){
	insert(1,n,1,who);
}
void erase(int who){
	erase(1,n,1,who);
}
int query(int l,int r,int w,int L,int R){
	if(L<=l && r<=R){
		if(t[w].empty())return 0;
		else return ((--t[w].end())->second);
	}
	int mid=l+r>>1,x=0,y=0;
	if(L<=mid)x=query(l,mid,w<<1,L,R);
	if(R>=mid+1)y=query(mid+1,r,w<<1|1,L,R);
	return atk[x]>atk[y]?x:y;
}
int fuck(int sta,int end){
	int ret=0;
	while(top[sta]!=top[end]){
		if(deep[top[sta]]>deep[top[end]]){
			int p=query(1,n,1,sub[top[sta]],sub[sta]);
			if(atk[p]>atk[ret])ret=p;
			sta=fa[top[sta]];
		}
		else{
			int p=query(1,n,1,sub[top[end]],sub[end]);
			if(atk[p]>atk[ret])ret=p;
			end=fa[top[end]];
		}
	}
	if(deep[sta]>deep[end]){
		int p=query(1,n,1,sub[end],sub[sta]);
		if(atk[p]>atk[ret])ret=p;
	}
	else{
		int p=query(1,n,1,sub[sta],sub[end]);
		if(atk[p]>atk[ret])ret=p;
	}
	return ret;
}
bool comp(const int &a,const int &b){
	return a>b;
}
void travel(int sta,int end){
	tt=0;
	for(int i=1;i<=k;i++){
		int p=fuck(sta,end);
		if(p!=0)ans[++tt]=p,erase(ans[tt]);
		else break;
	}
	for(int i=1;i<=tt;i++){
		insert(ans[i]);
	}
	for(int i=1;i<=tt;i++){
		ans[i]=atk[ans[i]];
	}
	sort(ans+1,ans+tt+1,comp);
}
int main(){
	int _q=30<<20;
	char *_p=(char*)malloc(_q)+_q;
	__asm__("movl %0, %%esp\n"::"r"(_p));
	freopen("knight.in","r",stdin);
	freopen("knight.out","w",stdout);
	splay(n);
	for(int i=1;i<n;i++){
		int x,y;splay(x),splay(y);
		addedge(x,y);addedge(y,x);
	}
	dfs(1,0),dfs(1,0,0);
	splay(m);
	for(int i=1;i<=m;i++){
		splay(atk[i]),splay(live[i]);
		insert(i);
	}
	splay(q),splay(k);
	for(int T=1;T<=q;T++){
		int opt,x,y;splay(opt),splay(x),splay(y);
		switch(opt){
			case 1:{
				travel(x,y);
				if(tt==0)puts("-1");
				else{
					for(int i=1;i<=tt;i++){
						printf("%d ",ans[i]);
					}
					putchar(10);
				}
				break;
			}
			case 2:{
				erase(x);live[x]=y;insert(x);
				break;
			}
			case 3:{
				erase(x);atk[x]=y;insert(x);
				break;
			}
		}
	}
}
//Copyright(c)2015 liuchenrui
#include<cstdio>
#include<ctime>
#include<iostream>
#include<algorithm>
#include<cstring>
#define H1 23333333ull
#define H2 10000007ull
#define H3 13908092295ull
#define ull unsigned long long
using namespace std;
inline void splay(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 n;
int f[3001][3001];
int m[3001];
int weight[3001];
ull hash[200010];
int size[200010];
struct Edge{
	int to,next;
}edge[2000010];
int Size,first[200010];
bool vis[200010];
bool son[200010];
int deep[200010];
void addedge(int x,int y){
	//fprintf(stderr,"%d %d\n",x,y);
	Size++;
	edge[Size].to=y;
	edge[Size].next=first[x];
	first[x]=Size;
}
int fa[20001];
int getfa(int v){
	if(v==fa[v])return v;
	return fa[v]=getfa(fa[v]);
}
int merge(int x,int y){
	int l=getfa(x),r=getfa(y);
	if(l>r)swap(l,r);
	fa[r]=l;
}
int getnum(int i,int j){
	return (i-1)*50+j;
}
struct Usort{
	ull size,deep,hash;
};
bool comp(const Usort &a,const Usort &b){
	if(a.hash!=b.hash)return a.hash<b.hash;
	if(a.deep!=b.deep)return a.deep<b.deep;
	return a.size<b.size;
}
Usort s[55];
void dfs(int now){
	hash[now]=17;vis[now]=true;size[now]=1;deep[now]=0;
	for(int u=first[now];u;u=edge[u].next){
		if(!vis[edge[u].to]){
			dfs(edge[u].to);
			size[now]+=size[edge[u].to];
			deep[now]=max(deep[now],deep[edge[u].to]+1);
			son[edge[u].to]=true;
		}
	}
	int sum=0;
	for(int u=first[now];u;u=edge[u].next){
		if(son[edge[u].to]){
			s[++sum]=(Usort){(ull)size[edge[u].to],(ull)deep[edge[u].to],hash[edge[u].to]};
			son[edge[u].to]=false;
		}
	}
	sort(s+1,s+sum+1,comp);
	for(int i=1;i<=sum;i++){
		hash[now]=hash[now]^s[i].hash*H1^s[i].deep*H2^s[i].size*H3;
	}
}
int main(){
//	int _q=70<<20;
//	char *_p=(char*)malloc(_q)+_q;
//	__asm__("movl %0, %%esp\n"::"r"(_p));
	freopen("family.in","r",stdin);
	freopen("family.out","w",stdout);
	splay(n);
	for(int i=1;i<=n;i++){
		splay(m[i]);fa[i]=i;
		for(int j=1;j<=m[i];j++){
			splay(f[i][j]);
			if(f[i][j]!=0){
				addedge(getnum(i,f[i][j]),getnum(i,j));
				addedge(getnum(i,j),getnum(i,f[i][j]));
			}
		}
	}
	int t=n;
	for(int i=1;i<=t;i++){
		weight[i]=getnum(i,1);
		for(int T=2;T<=m[i];T++){
			n++;fa[n]=i;
			for(int j=1;j<=m[i];j++){
				f[n][j]=f[i][j];
				if(f[i][j]!=0){
					addedge(getnum(n,f[n][j]),getnum(n,j));
					addedge(getnum(n,j),getnum(n,f[n][j]));
				}
			}
			weight[n]=getnum(n,T);
		}
	}
	for(int i=1;i<=n;i++){
		dfs(weight[i]);
	}
	for(int i=1;i<=n;i++){
		for(int j=1;j<=n;j++){
			if(hash[weight[i]]==hash[weight[j]]){
				merge(i,j);
			}
		}
	}
	for(int i=1;i<=t;i++){
		printf("%d\n",getfa(i));
	}
}


//Copyright(c)2015 liuchenrui
#include<cstdio>
#include<ctime>
#include<iostream>
#include<algorithm>
#include<cstring>
#define ll long long
using namespace std;
inline void splay(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;
}
ll dp[2001][2001];
ll p[2001];
ll n,m,k,mod;
int main(){
	freopen("candy.in","r",stdin);
	freopen("candy.out","w",stdout);
	cin>>n>>m>>k>>mod;
	for(ll i=1;i<=k;i++){
		dp[1][i]=1;
		p[i]=p[i-1]+1;
	}
	for(ll i=2;i<=m;i++){
		for(ll j=1;j<=k;j++){
			dp[i][j]=p[j];
			p[j]+=p[j-1];
			dp[i][j]%=mod,p[j]%=mod;
		}
	}
	ll t=0,ans=1;
	for(ll i=1;i<=k;i++){
		t+=dp[m][i];
		t%=mod;
	}
	for(ll i=1;i<=n;i++){
		ans*=t;t--;ans%=mod;
	}
	cout<<ans<<endl;
}


你可能感兴趣的:(总结)