7
10
2015
0

bzoj 4173 数学

这道题进去看status发现代码好短,肯定有什么规律,就把后面那部分打个表一看发现就是n*m然后就交了一发Wa了……以为结论是错的后来去找题解发现是对的,就是有个地方忘记mod了

至于证明吗看PoPoQQQ大神的题解吧: http://blog.csdn.net/PoPoQQQ/article/details/46820313

//coder : davidwang
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <climits>
#include <vector>
#include <queue>
#include <set>
#include <map>
#include <bitset>
#include <deque>
#include <iostream>
using namespace std;
#define LL long long
#define X first
#define Y second
template<typename T>
inline T sqr(const T &x){ return x*x; }
inline int read()
{
	int ret=0,f=1; char ch;
	for (ch=getchar();ch<'0' || ch>'9';ch=getchar())
		if (ch=='-') f=-f;
	for (;'0'<=ch && ch<='9';ch=getchar())
		ret=ret*10+ch-'0';
	return ret*f;
};
const int  mod = 998244353;
inline LL phi(LL x){
	LL i,ret=x;
	for (i=2;i*i<=x;i++){
		if (x%i==0){
			ret=ret/i*(i-1);
			while (x%i==0) x/=i;
		}
	}
	if (x!=1) ret=ret/x*(x-1);
	return ret;
}
int main()
{
#ifndef ONLINE_JUDGE
	freopen("a.in","r",stdin);
	freopen("a.out","w",stdout);
#endif
	LL n,m;
	cin>>n>>m;
	LL a=phi(n)%mod,b=phi(m)%mod;
	n%=mod; m%=mod;
	a=a*b%mod;
	a=a*n%mod;
	a=a*m%mod;
	cout<<a<<endl;
	return 0;
}

 

Category: 未分类 | Tags: bzoj 结论题
7
4
2015
0

今日跪卢爷之 bzoj 4160: [Neerc2009]Exclusive Access 2

首先这样一道题我这样的蒟蒻肯定是不会的了

只有卢爷很快就能秒掉这种题目拉

下面是我们的对话:

 “卢爷,4160怎么做?”

“4160,什么题阿?”于是打开bzoj开始翻"哦,这道题阿,我也不会做"

"那您是怎么A掉的?" "就是随便猜了个性质,就是求出独立集覆盖就可以了"

“为什么?” “你感受以下就是可以的”

于是我感受了一下

然后就没了

 
//coder : davidwang
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <climits>
#include <vector>
#include <queue>
#include <set>
#include <map>
#include <bitset>
#include <deque>
#include <iostream>
using namespace std;
#define LL long long
#define X first
#define Y second
template<typename T>
inline T sqr(const T &x){ return x*x; }
inline int read()
{
	int ret=0,f=1; char ch;
	for (ch=getchar();ch<'0' || ch>'9';ch=getchar())
		if (ch=='-') f=-f;
	for (;'0'<=ch && ch<='9';ch=getchar())
		ret=ret*10+ch-'0';
	return ret*f;
}
const int N = 15;
int a[N][N];
int list[200];
int f[1<<N],ok[1<<N];
int main()
{
#ifndef ONLINE_JUDGE
	freopen("a.in","r",stdin);
	freopen("a.out","w",stdout);
#endif
	int m=read(),n=0;
	char s1[3],s2[3];
	memset(list,-1,sizeof(list));
	for (int i=1;i<=m;i++){
		scanf("%s%s",s1,s2);
		if (list[s1[0]]==-1) list[s1[0]]=n++;
		if (list[s2[0]]==-1) list[s2[0]]=n++;
		int x=list[s1[0]],y=list[s2[0]];
		a[x][y]=a[y][x]=1;
	}
	for (int s=1;s<(1<<n);s++){
		ok[s]=1;
		for (int j=0;j<n;j++)
			if (s>>j&1)
				for (int k=0;k<n;k++)
					if (s>>k&1)
						if (a[j][k] || a[k][j])
							ok[s]=0;	
	}
	for (int s=1;s<(1<<n);s++){
		f[s]=100000;
		if (ok[s]){
			f[s]=1; continue;
		}
		for (int s0=(s-1)&s;s0;s0=(s0-1)&s){
			if (ok[s0] && f[s^s0]<f[s]) f[s]=f[s^s0]+1;
		}
	}
	printf("%d\n",f[(1<<n)-1]-2);
	return 0; 
}

 

 

6
29
2015
2

【bzoj2229】[Zjoi2011]最小割

首先学习一下fhq的最小割树理论

应该是比较好理解的,然后只需要求n此最小割就可以得到任意两点之间的最小割了,因为大错一个字母然后拜样例所赐一直在疯狂的wa然后……然后&然后就没有了

//coder : davidwang
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <ctime>
#include <climits>
#include <queue>
#include <deque>
#include <iostream>
#include <stack>
#include <set>
#include <map>
#include <string>
#include <algorithm>
#include <vector>
#include <algorithm>
using namespace std;
#define LL long long
#define PII pair<int,int>
#define X first
#define Y second
inline int read()
{
	int ret=0,f=1; char ch;
	for (ch=getchar();ch<'0' || ch>'9';ch=getchar())
		if (ch=='-') f=-f;
	for (;'0'<=ch && ch<='9';ch=getchar())
		ret=ret*10+ch-'0';
	return ret*f;
}
const int N = 155,M=3010;
struct edge{
	int to,flow;
	edge(int to=0,int flow=0):to(to),flow(flow){}
}e[M*2];
vector<int>g[N];
int vis[N],q[N],d[N],cnt;
inline void connect(int x,int y,int f){
	e[cnt]=edge(y,f); g[x].push_back(cnt++);
	e[cnt]=edge(x,f); g[y].push_back(cnt++);
}
int s,t,n,m;
int bfs(){
	int head=0,tail=1,u,v;
	memset(d,0,sizeof(d));
	q[1]=s; d[s]=1;
	while (head<tail){
		u=q[++head];
		for (vector<int>::iterator it=g[u].begin();it!=g[u].end();it++){
			if (e[*it].flow && d[e[*it].to]==0){
				d[e[*it].to]=d[u]+1;
				q[++tail]=e[*it].to;
			}
		}
	}
	return d[t];
}
int dfs(int x,int flow){
	if (x==t || flow==0) return flow;
	int f,totflow=0;
	for (vector<int>::iterator it=g[x].begin();it!=g[x].end();it++){
		if (e[*it].flow && d[e[*it].to]==d[x]+1){
			f=dfs(e[*it].to,min(flow,e[*it].flow));
			totflow+=f; flow-=f;
			e[*it].flow-=f; e[(*it)^1].flow+=f;
			if (flow==0) return totflow;
		}
	}
	if (flow)d[x]=0;
	return totflow;
}
inline int dinic()
{
	int ret=0;
	while (bfs()) ret+=dfs(s,INT_MAX);
	return ret;
}
			
int ans[N][N];
inline void rebuild(){
	for (int i=0;i<cnt;i+=2)
		e[i].flow=e[i+1].flow=(e[i].flow+e[i+1].flow)/2;	
}
int a[N],list[N];
void solve(int l,int r){
	if (l==r) return;
	rebuild();
	s=a[l],t=a[r];
	int Flow=dinic();
	for (int i=1;i<=n;i++)
		if (d[i])
			for (int j=1;j<=n;j++)
				if (d[j]==0)
					ans[i][j]=ans[j][i]=min(ans[i][j],Flow);
	int L=l,R=r;
	for (int i=l;i<=r;i++){
		if (d[a[i]])
			list[L++]=a[i];
		else list[R--]=a[i];
	}
	for (int i=l;i<=r;i++) a[i]=list[i];
	solve(l,L-1); solve(R+1,r);
}
int main()
{
#ifndef ONLINE_JUDGE
	freopen("a.in","r",stdin);
	freopen("a.out","w",stdout);
#endif
	int T=read();
	while (T--){
		cnt=0; for (int i=1;i<=n;i++) g[i].clear();
		memset(ans,127,sizeof(ans));
		n=read(); m=read();
		for (int i=1;i<=m;i++){
			int x=read(),y=read(),z=read();
			connect(x,y,z);
		}
		for (int i=1;i<=n;i++) a[i]=i;
		solve(1,n);
		int Q=read();
		while (Q--){
			int now=read(),ret=0;
			for (int i=1;i<=n;i++)
				for (int j=i+1;j<=n;j++)
					if (ans[i][j]<=now) ret++;
			printf("%d\n",ret);
		}
		puts("");
	}
	return 0;
}

 

Category: 未分类 | Tags: bzoj 最小割 最小割树
6
23
2015
0

bzoj 2566: xmastree

第一次写维护点分治的树

然后因为大错一个数字调了半个小时是在蛋疼,最近开的坑太多赶脚没有时间填了

算了一点点来吧

//coder : davidwang
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <climits>
#include <vector>
#include <queue>
#include <set>
#include <map>
#include <bitset>
#include <deque>
#include <iostream>
using namespace std;
#define LL long long
#define X first
#define Y second
template<typename T>
inline T sqr(const T &x){ return x*x; }
inline int read()
{
	int ret=0,f=1; char ch;
	for (ch=getchar();ch<'0' || ch>'9';ch=getchar())
		if (ch=='-') f=-f;
	for (;'0'<=ch && ch<='9';ch=getchar())
		ret=ret*10+ch-'0';
	return ret*f;
}
const int N = 12010;
int start[N],to[N<<1],next[N<<1],len[N<<1],cnt,size[N],q[N],d[N];
int vis[N],use[N],fa[N],Pre[N],col[N],fl[N],inf=INT_MAX,p[N][20],pl[N][20];
int n,m,T;
multiset<pair<int,int> >S[N];
multiset<int>ans;
multiset<pair<int,int> >::iterator it,i1,i2;
inline void connect(int x,int y,int l){
	to[++cnt]=y; next[cnt]=start[x]; start[x]=cnt; len[cnt]=l;
}
inline int bfs(int x,int flag=0)
{
	vis[x]=1;
	int head=0,tail=1,u,v;
	q[1]=x; vis[x]=1;
	while (head<tail){
		u=q[++head];
		for (int p=start[u];p;p=next[p]){
			if (!vis[to[p]]&&!use[to[p]]){
				q[++tail]=to[p];
				fa[to[p]]=u;
				vis[to[p]]=1;
				if (flag==2){
					d[to[p]]=d[u]+1;
					fl[to[p]]=len[p];
				}
			}
		}
	}
	for (int i=1;i<=tail;i++) vis[q[i]]=0;
	if (flag==0||flag==2){
		return tail;
	}
	for (int i=1;i<=tail;i++){
		int x=q[i];
		size[x]=0;
	}
	int Max=tail+1,cur=0,y=-1;
	for (int i=tail;i;i--){
		int x=q[i];
		size[x]++; size[fa[x]]+=size[x];
		cur=0;
		for (int p=start[x];p;p=next[p])
			if (to[p]!=fa[x] && vis[to[p]]){
				cur=max(cur,size[to[p]]);
			}
			
		cur=max(cur,tail-size[x]);
		if (cur<Max){
			Max=cur;
			y=x;
		}
	}
	return y;
}
inline int lca(int x,int y){
	if (d[x]<d[y]) swap(x,y);
	int ans=0,j;
	while (d[x]>d[y]){
		for (j=1;d[p[x][j]]>=d[y];j++);
		ans+=pl[x][j-1]; x=p[x][j-1];
	}
	while (x!=y){
		for (j=1;p[x][j]!=p[y][j];j++);
		ans+=pl[x][j-1]+pl[y][j-1];
		x=p[x][j-1],y=p[y][j-1];
	}
	return ans;
}
void dfs(int x,int f){
	x=bfs(x,1);
	int n=bfs(x,0);
	use[x]=1; Pre[x]=f;
	for (int i=1;i<=n;i++)
		S[x].insert(make_pair(col[q[i]],lca(q[i],x)));
	int nowC=0,tot=0,flag=0;
	for (it=S[x].begin();it!=S[x].end();it++){
		if (it->X!=nowC){
			nowC=it->X;
			tot=0; flag=0;
		}
		if (it->X==nowC){
			tot++;
			if (tot<=2) flag+=it->Y;
			if (tot==2) ans.insert(flag);
		}
	}
	for (int p=start[x];p;p=next[p])
		if (!use[to[p]]) dfs(to[p],x);
}
inline int Make_Ans(multiset<pair<int,int> >& S,int c){
	i1=i2=S.upper_bound(make_pair(c,-1));
	if (i1==S.end() || i1->X!=c) return inf;
	i2++;
	if (i2==S.end() || i2->X!=c) return inf;
	int ret=i1->Y+i2->Y;
	return ret;
}
void modify(int x,int y,int c1,int c2){
	if (x==0) return;
	int d=lca(x,y);
	set<int>::iterator now=ans.find(Make_Ans(S[x],c1));
	if (now!=ans.end()) ans.erase(now);
	S[x].erase(S[x].find(make_pair(c1,d)));
	ans.insert(Make_Ans(S[x],c1));
	
	now=ans.find(Make_Ans(S[x],c2));
	if (now!=ans.end()) ans.erase(now);
	S[x].insert(make_pair(c2,d));
	ans.insert(Make_Ans(S[x],c2));
	
	modify(Pre[x],y,c1,c2);
}
int init()
{
#ifndef ONLINE_JUDGE
	freopen("a.in","r",stdin);
	freopen("a.out","w",stdout);
#endif
	n=read();
	for (int i=1;i<=n;i++) col[i]=read();
	for (int i=1;i<n;i++){
		int x=read(),y=read(),z=read();
		connect(x,y,z);
		connect(y,x,z);
	}
	bfs(1,2); d[0]=-1;
	for (int i=1;i<=10;i++) ans.insert(inf); 
	for (int i=1;i<=n;i++) p[i][0]=fa[i],pl[i][0]=fl[i];
	for (int j=1;j<20;j++)
		for (int i=1;i<=n;i++)
			p[i][j]=p[p[i][j-1]][j-1],
			pl[i][j]=pl[i][j-1]+pl[p[i][j-1]][j-1];
	dfs(1,0);
	return 0;
}
inline void show(){
	printf("show=====\n");
	for (multiset<int>::iterator it=ans.begin();it!=ans.end();it++)
		printf("%d ",*it);
	printf("\nover=====\n");
}
void work()
{
	T=read();
	printf("%d\n",*ans.begin());
//	show();
	while (T--){
		int x=read(),c=read();
		modify(x,x,col[x],c);
		col[x]=c;
		printf("%d\n",*ans.begin());
//		show();
	}
}
int main()
{
	init();
	work();
	return 0;
}

 

Category: 未分类 | Tags: bzoj 点分治 点分治树
6
23
2015
0

bzoj 4155: [Ipsc2015]Humble Captains

第一问: 网络流,这并没有什么问题

第二问: 阿丽和桃子的游戏,这并没有什么问题

总之是傻逼了

//coder : davidwang
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <climits>
#include <algorithm>
#include <vector>
#include <bitset>
using namespace std;
#define LL long long
#define X first
#define Y second
inline int read()
{
	int ret=0,f=1; char ch;
	for (ch=getchar();ch<'0' || ch>'9';ch=getchar())
		if (ch=='-') f=-f;
	for (;'0'<=ch && ch<='9';ch=getchar())
		ret=ret*10+ch-'0';
	return ret*f;
}
const int N = 210;
struct edge{
	int to,flow;
	edge(int to=0,int flow=0): to(to),flow(flow){}
}e[N*N*2];
int d[N],f[N*N*2],x[N],n,m,cnt,q[N];
vector<int>g[N];
bitset<N*N>A;
inline void connect(int a,int b,int f){
	e[cnt]=edge(b,f);
	g[a].push_back(cnt++);
	x[a]++;
	e[cnt]=edge(a,f);
	g[b].push_back(cnt++);
	x[b]++;
}
int s=1,t=2;
inline int bfs()
{
	int head=0,tail=1,u,v;
	for (int i=1;i<=n;i++) d[i]=0;
	d[s]=1; q[1]=s;
	while (head<tail){
		u=q[++head];
		for (vector<int>::iterator it=g[u].begin();it!=g[u].end();it++){
			if (e[*it].flow && !d[e[*it].to]){
				q[++tail]=e[*it].to;
				d[e[*it].to]=d[u]+1;
			}
		}
	}
	return d[t];
}
inline int dfs(int x,int flow){
	if (x==t || flow==0) return flow;
	int totflow=0,f;
	for (vector<int>::iterator it=g[x].begin();it!=g[x].end();it++){
		if (e[*it].flow && d[e[*it].to]==d[x]+1){
			f=dfs(e[*it].to,min(flow,e[*it].flow));
			flow-=f; totflow+=f;
			e[*it].flow-=f; e[(*it)^1].flow+=f;
			if (flow==0) return totflow;
		}
	}
	if (flow) d[x]=-1;
	return totflow;
}
inline void work()
{
	int ans1=0,ans2=0;
	n=read(); m=read();
	cnt=0;
	for (int i=1;i<=n;i++){
		g[i].clear();
		x[i]=0;
	}
	int cE=m; 
	for (int i=1;i<=m;i++){
		int x=read(),y=read();
		if (x+y==3) cE--;
		else connect(x,y,1);
	}
	for (int i=0;i<=m*2;i++) A[i]=0;
	A[x[1]]=1;
	while (bfs()) ans1+=dfs(s,INT_MAX);
	printf("%d ",cE-ans1);
	for (int i=3;i<=n;i++){
		A=(A<<x[i]|A);
	}
	for (int i=0;i<=cE;i++){
		if (A[cE+i]==1 || A[cE-i]==1){
			printf("%d\n",i);
			break;
		}
	}
}
int main()
{
#ifndef ONLINE_JUDGE
	freopen("a.in","r",stdin);
	freopen("a.out","w",stdout);
#endif
	int T=read();
	while (T--) work();
	return 0;
}

 

Category: 未分类 | Tags: bzoj ipsc 网络流 贪心
6
18
2015
0

bzoj 4152: [AMPPZ2014]The Captain

首先按照x,y分别排序相邻的连边然后跑最短路,这个应该是显然的,不知道用了什么卡SPFA的方法,必须用堆+Dij

//coder : davidwang
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <vector>
#include <queue>
#include <bitset>
#include <deque>
using namespace std;
#define LL long long
#define X first
#define Y second
template<typename T>
inline T sqr(const T &x){ return x*x; }
inline int read()
{
	int ret=0,f=1; char ch;
	for (ch=getchar();ch<'0' || ch>'9';ch=getchar())
		if (ch=='-') f=-f;
	for (;'0'<=ch && ch<='9';ch=getchar())
		ret=ret*10+ch-'0';
	return ret*f;
}
const int N = 200010;
const LL inf = 1LL<<60;
struct point{
	int x,y,pos;
}a[N];
int start[N],next[N<<2],to[N<<2],len[N<<2],cnt;
struct node{
	LL d;
	int id;
	int operator<(const node &x)const {
		return d>x.d;
	}
	node(int id=0,LL d=0):id(id),d(d){}
};
LL d[N];
priority_queue<node>Q;
int vis[N];
inline int cmp1(const point &a,const point &b){
	return a.x<b.x;
}
inline int cmp2(const point &a,const point &b){
	return a.y<b.y;
}
inline void connect(int x,int y,int d){
	to[++cnt]=y; next[cnt]=start[x];
	start[x]=cnt; len[cnt]=d;
}
int n;
int main()
{
#ifndef ONLINE_JUDGE
	freopen("a.in","r",stdin);
	freopen("a.out","w",stdout);
#endif
	n=read();
	for (int i=1;i<=n;i++){
		a[i].x=read();
		a[i].y=read();
		a[i].pos=i;
	}
	sort(a+1,a+n+1,cmp1);
	for (int i=1;i<n;i++){
		connect(a[i].pos,a[i+1].pos,a[i+1].x-a[i].x);
		connect(a[i+1].pos,a[i].pos,a[i+1].x-a[i].x);
	}
	sort(a+1,a+n+1,cmp2);
	for (int i=1;i<n;i++){
		connect(a[i].pos,a[i+1].pos,a[i+1].y-a[i].y);
		connect(a[i+1].pos,a[i].pos,a[i+1].y-a[i].y);
	}
	for (int i=2;i<=n;i++) d[i]=inf;
	Q.push(node(1,0));
	while (!Q.empty()){
		while (Q.size() && vis[Q.top().id]) Q.pop();
		if (Q.empty()) break;
		int x=Q.top().id; Q.pop();
		vis[x]=1;
		for (int p=start[x];p;p=next[p]){
			if (d[to[p]]>d[x]+len[p]){
				d[to[p]]=d[x]+len[p];
				Q.push(node(to[p],d[to[p]]));
			}
		}
		if (vis[n]) break;
	}
	printf("%lld\n",d[n]);
	return 0;
}

 

Category: 未分类 | Tags: bzoj 堆优化Dij
6
17
2015
0

bzoj 4144: [AMPPZ2014]Petrol

就是一结论题目

首先如果所有点都是加油站,那么把询问离线维护可达的生成森林就OK了

现在有些点不是加油站

我们预处理出每个不是加油站的点距离最近的加油站,就变成了一个蜘蛛网的结构(其实是一个树)

然后我们对于原来的每条边对应这两个加油站之间的边如果原来有一条(x,y,d)的边,记bel[x]表示距离x最近的加油站,d[x]表示距离x最近的加油站的距离,那么这样一条边对应着(bel[x],bel[y],d+d[x]+d[y])这样一个点,然后问题就解决了

证明:

我还是大体证明了以下这个结论(其实就一个拟阵)

//coder : davidwang
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <vector>
#include <queue>
#include <bitset>
#include <deque>
using namespace std;
#define LL long long
#define X first
#define Y second
template<typename T>
inline T sqr(const T &x){ return x*x; }
inline int read()
{
	int ret=0,f=1; char ch;
	for (ch=getchar();ch<'0' || ch>'9';ch=getchar())
		if (ch=='-') f=-f;
	for (;'0'<=ch && ch<='9';ch=getchar())
		ret=ret*10+ch-'0';
	return ret*f;
}
const int N = 200010;
const LL inf = 1LL<<60;
struct edge{
	int x,y,l,pos;
	edge(int x=0,int y=0,int l=0,int pos=0): x(x),y(y),l(l),pos(pos){}
	int operator<(const edge &A) const{
		return l<A.l || (l==A.l && pos<A.pos);
	}
}e[N*4];
vector<pair<int,int> >g[N];
vector<pair<int,int> >::iterator it;
int q[N+2],bel[N],ans[N],in[N];
LL d[N];
inline int next(int &x){ x=(x%N+1); return x;}
struct UnionFindSet{
	int Set[N],Size[N];
	inline void init(int n){
		for (int i=1;i<=n;i++){
			Set[i]=i;
			Size[i]=1;
		}
	}
	int find(int x){
		if (Set[x]==x) return x;
		Set[x]=find(Set[x]);
		return Set[x];
	}
	inline int join(int x,int y){
		x=find(x),y=find(y);
		if (x==y) return 0;
		if (Size[x]>Size[y]) swap(x,y);
		Set[x]=y; Size[y]+=Size[x];
		return 1;
	}
}s;
int n,m,T,cnt,E;
int main()
{
#ifndef ONLINE_JUDGE
	freopen("a.in","r",stdin);
	freopen("a.out","w",stdout);
#endif
	n=read(); m=read(); E=read();
	for (int i=1;i<=n;i++) d[i]=inf;
	for (int i=1;i<=m;i++){
		int x=read();
		bel[x]=x;
		d[x]=0;
		in[x]=1;
		q[i]=x;
	}
	for (int i=1;i<=E;i++){
		int x=read(),y=read(),z=read();
		g[x].push_back(make_pair(y,z));
		g[y].push_back(make_pair(x,z));
	}
	int head=0,tail=m;
	while (head!=tail){
		int u=q[next(head)];
		for (it=g[u].begin();it!=g[u].end();it++){
			if (d[it->X]>d[u]+it->Y){
				d[it->X]=d[u]+it->Y;
				bel[it->X]=bel[u];
				if (!in[it->X]){
					q[next(tail)]=it->X;
					in[it->X]=1;
				}
			}
		}
		in[u]=0;
	}
	for (int i=1;i<=n;i++)
		for (it=g[i].begin();it!=g[i].end();it++)
			if (bel[it->X] != bel[i]){
				LL now=d[i]+d[it->X]+it->Y;
				if (now>2e9) continue;
				e[++cnt]=edge(bel[i],bel[it->X],(int)now);
			}
	T=read();
	for (int i=1;i<=T;i++){
		cnt++;
		e[cnt].x=read(); e[cnt].y=read();
		e[cnt].l=read();
		e[cnt].pos=i;
	}
	sort(e+1,e+cnt+1);
	s.init(n);
	for (int i=1;i<=cnt;i++){
		if (e[i].pos==0)
			s.join(e[i].x,e[i].y);
		else
			ans[e[i].pos]=s.find(e[i].x)==s.find(e[i].y);
	}
	for (int i=1;i<=T;i++) printf("%s\n",ans[i]?"TAK":"NIE");
	return 0;
}

 

Category: 未分类 | Tags: bzoj 并查集 拟阵
6
17
2015
0

bzoj 4080: [Wf2014]Sensor Network

死活过不去的暴力?难道这就是传说中的卡最大团的暴力数据??

上网一看全都是随机化,然后完全不明白

后来想了想什么random_shuffle之后搞一下

然后就过了

对了,次数还可以卡以下所以就把T搞到80才rank3

//coder : davidwang
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <vector>
#include <queue>
#include <bitset>
#include <deque>
using namespace std;
#define LL long long
#define X first
#define Y second
template<typename T>
inline T sqr(const T &x){ return x*x; }
inline int read()
{
	int ret=0,f=1; char ch;
	for (ch=getchar();ch<'0' || ch>'9';ch=getchar())
		if (ch=='-') f=-f;
	for (;'0'<=ch && ch<='9';ch=getchar())
		ret=ret*10+ch-'0';
	return ret*f;
}
const int N = 110;
bitset<N>now,ans,cur,a[N],can;
int order[N],x[N],y[N],d,n;
int main()
{
#ifndef ONLINE_JUDGE
	freopen("a.in","r",stdin);
	freopen("a.out","w",stdout);
#endif
//	srand(2333);
	n=read(); d=read();
	d*=d;
	for (int i=1;i<=n;i++){
		x[i]=read();
		y[i]=read();
		for (int j=1;j<i;j++){
			if (sqr(x[i]-x[j])+sqr(y[i]-y[j])<=d){
				a[i][j]=a[j][i]=1;
			}
		}
	}
	for (int i=1;i<=n;i++) order[i]=i;
	for (int T=1;T<=80;T++){
		for (int i=1;i<=n;i++) can[i]=1,now[i]=0;
		for (int i=1;i<=n;i++){
			if (can[order[i]]){
				can=can&a[order[i]];
				now[order[i]]=1;
			}
		}
		if (now.count()>ans.count()) ans=now;
		random_shuffle(order+1,order+n+1);
	}
	printf("%d\n",(int)ans.count());
	for (int i=1;i<=n;i++){
		if (ans[i]) printf("%d ",i);
	}
	puts("");
	return 0;
}
Category: 未分类 | Tags: bzoj 随机化 乱搞
6
16
2015
0

bzoj 4134: ljw和lzr的hack比赛

我才不会说是被题目吸引进来的

然后就吓傻了,我还以为是那种朴素的森林取子问题,节点sg就是字节点抑或+1然后错的酸爽,然后赶紧问

原来并没有什么结论因为一些点已经被放了

然后就只能暴力计算sg的值,可以使用Trie树搞一搞,然后膜了一下huzecong的题解

……

//coder : davidwang
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <vector>
#include <queue>
#include <deque>
using namespace std;
#define LL long long
#define X first
#define Y second
inline int read()
{
	int ret=0,f=1; char ch;
	for (ch=getchar();ch<'0' || ch>'9';ch=getchar())
		if (ch=='-') f=-f;
	for (;'0'<=ch && ch<='9';ch=getchar())
		ret=ret*10+ch-'0';
	return ret*f;
}
const int N = 100010,Log=17;
struct node{
	int lch,rch,d,flag;
}s[N*Log*2];
#define l(x) s[x].lch
#define r(x) s[x].rch
int root[N],sg[N],vis[N],sum[N],up[N],fa[N],n,a[N],cnt,tot,ans[N];
vector<int>g[N];
inline int reverse(int x){
	int ret=0;
	for (int i=1;i<=Log;i++)
		if (x>>i-1&1) ret+=1<<Log-i;
	return ret;
}
inline void push_up(int x){
	s[x].flag=s[l(x)].flag && s[r(x)].flag;
}
inline void push_down(int x){
	if (s[x].d){
		if (l(x)) s[l(x)].d^=s[x].d>>1;
		if (r(x)) s[r(x)].d^=s[x].d>>1;
		if (s[x].d&1) swap(l(x),r(x));
		s[x].d=0;
	}
}
inline int getans(int x){
	int ret=0;
	for (int i=Log;x;i--){
		push_down(x);
		if (s[l(x)].flag){
			ret+=1<<i-1;
			x=r(x);
		}else x=l(x);
	}
	return ret;
}
inline void insert(int x,int num,int d){
	push_down(x);
	if (num>>d-1&1){
		if (r(x)==0) r(x)=++cnt;
		if (d!=1) insert(r(x),num,d-1);
		else s[r(x)].flag=1;
	}else{
		if (l(x)==0) l(x)=++cnt;
		if (d!=1) insert(l(x),num,d-1);
		else s[l(x)].flag=1;
	}
	push_up(x);
}
int merge(int l,int r){
	if (l==0 || s[r].flag) return r;
	if (r==0 || s[l].flag) return l;
	push_down(r); push_down(l);
	int now = ++cnt;
	l(now)=merge(l(l),l(r));
	r(now)=merge(r(l),r(r));
	push_up(now);
	return now;
}
inline void init()
{
#ifndef ONLINE_JUDGE
	freopen("a.in","r",stdin);
	freopen("a.out","w",stdout);
#endif
	n=read();
	for (int i=1;i<=n;i++) a[i]=read();
	for (int i=1;i<n;i++){
		int x=read(),y=read();
		g[x].push_back(y);
		g[y].push_back(x);
	}
	for (int i=1;i<=n;i++){
		root[i]=++cnt;
	}
}
inline void dfs(int x){
	for (vector<int>::iterator it=g[x].begin();it!=g[x].end();it++){
		if (*it==fa[x]) continue;
		fa[*it]=x;
		dfs(*it);
		sum[x]^=sg[*it];
	}
	for (vector<int>::iterator it=g[x].begin();it!=g[x].end();it++){
		if (*it==fa[x]) continue;
		s[root[*it]].d^=reverse(sg[*it]^sum[x]);
		root[x]=merge(root[x],root[*it]);
	}
	if (a[x]==0) insert(root[x],sum[x],Log);
	sg[x]=getans(root[x]);
}
inline void calc(int x){
	if ((up[x]^sum[x])==0 && a[x]==0) ans[++tot]=x;
	for (vector<int>::iterator it=g[x].begin();it!=g[x].end();it++){
		if (*it==fa[x]) continue;
		up[*it]=up[x]^sum[x]^sg[*it];
		calc(*it);
	}
	return;
}
inline void print()
{
	if (tot==0){ puts("-1"); return ;}
	sort(ans+1,ans+tot+1);
	for (int i=1;i<=tot;i++){
		printf("%d\n",ans[i]);
	}
}
int main()
{
	init();
	dfs(1);
//	for (int i=1;i<=n;i++) printf("%d\n",sg[i]);
	calc(1);
	print();
	return 0;
}

 

 

6
14
2015
0

bzoj 4129: Haruna’s Breakfast

首先改成待修该的树上莫队,然后就发现题目变成了一个要求维护一个集合,加入一个数字,修改一个数字(这两个操作要求O(1)完成)然后询问这个集合的mex值 $$ O(n^{2/3}) $$ 以内完成

然后我想了半天发现修改可以用树状数组,询问可以二分,然后这么又非常逗比的想到了分块大法好这样询问就是$$ O(n^{0.5}) $$ 了

//coder : davidwang
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>
#include <vector>
#include <cmath>
#include <ctime>
#include <iostream>
using namespace std;
#define LL long long
#define LD long double
#define X first
#define Y second
inline int read()
{
    int ret=0,f=1; char ch;
    for (ch=getchar();ch>'9' || ch<'0';ch=getchar())
        if (ch=='-') f=-f;
    for (;'0'<=ch && ch<='9';ch=getchar())
        ret=ret*10+ch-'0';
    return ret*f;
}
const int N = 50010;
int start[N],to[N<<1],next[N<<1],cnt;
int stack[N],bel[N],dfn[N],p[N][20],d[N],fa[N],now,tot,top,col[N];
int a[N],vis[N],n,m,t1,t2;
int block[N],num[N],g[N],l[N],r[N],B,C,D;
int ans[N];
struct query{
	int x,y,t,pos;
	int operator < (const query &A) const {
		if (bel[x]!=bel[A.x]) return bel[x]<bel[A.x];
		if (bel[y]!=bel[A.y]) return bel[y]<bel[A.y];
		return t<A.t;
	}
}Q[N];
struct modify{
	int x,y,pre;
}A[N];
inline void connect(int x,int y){
	to[++cnt]=y; next[cnt]=start[x]; start[x]=cnt;
}
void dfs(int x){
	dfn[x]=++now;
	int bot=top;
	for (int p=start[x];p;p=next[p]){
		int &y=to[p];
		if (y==fa[x]) continue;
		fa[y]=x;  
		d[y]=d[x]+1;
		dfs(y);
		if (top-bot>B){
			tot++;
			while (top>bot) bel[stack[top--]]=tot;
			bel[stack[top--]]=tot;
		}
	}
	stack[++top]=x;
}
int init()
{
#ifndef ONLINE_JUDGE
	freopen("a.in","r",stdin);
	freopen("a.out","w",stdout);
#endif
	n=read(),m=read();
	for (int i=1;i<=n;i++) col[i]=a[i]=read();
	for (int i=1;i<n;i++){
		int x=read(),y=read();
		connect(x,y);
		connect(y,x);
	}
	B = pow(n,2.0/3),C=sqrt(n),D=(n+1)/C+((n+1)%C!=0);
	for (int i=0;i<D;i++){
		l[i]=i*C; r[i]=min(n,(i+1)*C-1);
	}
	d[1]=1;
	dfs(1); tot++;
	while (top) bel[stack[top--]]=tot;
	for (int i=1;i<=m;i++){
		int op=read(),x=read(),y=read();
		if (op==0){
			A[++t2].x=x;
			A[t2].y=y; A[t2].pre=col[x];
			col[x]=y;
		}else{
			t1++;
			if (dfn[x]>dfn[y]) swap(x,y);
			Q[t1].x=x; Q[t1].y=y;
			Q[t1].pos=t1; Q[t1].t=t2;
		}
	}
	sort(Q+1,Q+t1+1);
	for (int i=1;i<=n;i++) p[i][0]=fa[i];
	for (int j=1;j<20;j++)
		for (int i=1;i<=n;i++) p[i][j]=p[p[i][j-1]][j-1];
	return 0;
} 
inline int lca(int x,int y){
	if (d[x]<d[y]) swap(x,y);
	int j;
	while (d[x]>d[y]){
		for (j=1;d[p[x][j]]>=d[y];j++);
		x=p[x][j-1];
	}
	while (x!=y){
		for (j=1;p[x][j]!=p[y][j];j++);
		x=p[x][j-1],y=p[y][j-1];
	}
	return x;
}
inline void reverse(int x){
	if (vis[x]){
		vis[x]=0;
		if (a[x]>n) return;
		num[a[x]]--;
		if (num[a[x]]==0){
			g[a[x]/C]--;
		}
	}else{
		vis[x]=1;
		if (a[x]>n) return;
		num[a[x]]++;
		if (num[a[x]]==1){
			g[a[x]/C]++;
		}
	}
}
inline int getans(){

	for (int i=0;i<D;i++){
		if (g[i]==r[i]-l[i]+1) continue;
		for (int j=l[i];j<=r[i];j++){
			if (num[j]==0) return j;
		}
	}

//	for (int i=0;;i++) if (num[i]==0) return i;
	return n;
}
inline void change(int x,int y){
	if (vis[x]){
		reverse(x);
		a[x]=y;
		reverse(x);
	}else a[x]=y;
}
inline void solve(int x,int y){
	while (x!=y){
		if (d[x]>d[y]) reverse(x),x=fa[x];
		else reverse(y),y=fa[y];
	}
}
void work()
{
	for (int i=1;i<=Q[1].t;i++) change(A[i].x,A[i].y);
	solve(Q[1].x,Q[1].y); 
	int u=lca(Q[1].x,Q[1].y); 
	reverse(u); ans[Q[1].pos]=getans(); reverse(u);
	for (int i=2;i<=t1;i++){
		if (Q[i].t>Q[i-1].t) for (int j=Q[i-1].t+1;j<=Q[i].t;j++) change(A[j].x,A[j].y);
		if (Q[i].t<Q[i-1].t) for (int j=Q[i-1].t;j>Q[i].t;j--) change(A[j].x,A[j].pre);
		u=lca(Q[i].x,Q[i].y);
		solve(Q[i].x,Q[i-1].x);
		solve(Q[i].y,Q[i-1].y);
		reverse(u);
		ans[Q[i].pos]=getans();
		reverse(u);
	}
	for (int i=1;i<=t1;i++)
		printf("%d\n",ans[i]);
	return;
}
int main()
{
	init();
	work();
	return 0;
}

 

Host by is-Programmer.com | Power by Chito 1.3.3 beta | Theme: Aeros 2.0 by TheBuckmaker.com