记录编号 84923 评测结果 AAAAAAAAAA
题目名称 [NOI 1996]三角形灯塔 最终得分 100
用户昵称 Gravatarcstdio 是否通过 通过
代码语言 C++ 运行时间 0.034 s
提交时间 2013-12-21 20:40:51 内存使用 0.23 MiB
显示代码纯文本
#include<iostream>
#include<cstdio>
#include<cmath>
#include<algorithm>
#include<cstring>
#include<vector>
#include<queue>
#include<iomanip>
using namespace std;
const int SIZEN=51;
typedef long long ll;
int N,P;
ll notation[SIZEN][SIZEN]={0};//二进制表示
ll pow2[60]={1};
int ps[SIZEN]={0};//P个灯的状态
ll pn[SIZEN]={0};//P个灯的表示
int getdig(ll x,int k){//第k位是2^k-1
	return (x&pow2[(k-1)])>>(k-1);
}
void changedig(ll &x,int k,int t){//x的第k位变成t
	if(t) x|=pow2[k-1];
	else x&=(~pow2[k-1]);
}
void printdig(ll x){//调试接口,输出x表示的状态
	for(int i=1;i<=N;i++) cout<<getdig(x,i);
}
void solve(void){
	int i,j,k;
	int a,b;
	ll ans=0;
	for(j=1;j<=P;j++){//P个方程至多消去P个未知数
		for(k=j;k<=N;k++){
			for(i=j;i<=P;i++){
				if(i<=P&&getdig(pn[i],k)) goto OF;
			}
		}
		OF:;
		if(i==P+1) continue;//无效元素
		ans++;
		if(k!=j){//交换列
			for(i=1;i<=P;i++){
				a=getdig(pn[i],j),b=getdig(pn[i],k);
				changedig(pn[i],j,b);
				changedig(pn[i],k,a);
			}
		}
		if(i!=j) swap(pn[i],pn[j]);swap(ps[i],ps[j]);//交换行
		for(i=1;i<=P;i++){
			if(i==j||!getdig(pn[i],j)) continue;
			pn[i]^=pn[j];
			ps[i]^=ps[j];
		}
	}
	for(i=1;i<=P;i++){
		if(!pn[i]&&ps[i]){
			printf("No Answer!\n");
			return;
		}
	}
	ans=N-ans;
	ans=pow2[ans];
	cout<<ans<<endl;
}
void getnotation(void){
	int i,j;
	for(i=1;i<=N;i++) notation[N][i]=pow2[i-1];//只有i起作用
	for(i=N-1;i>=1;i--){
		for(j=1;j<=i;j++){
			notation[i][j]=(notation[i+1][j]^notation[i+1][j+1]);
		}
	}
}
void init(void){
	for(int i=1;i<=51;i++) pow2[i]=pow2[i-1]*2;
	scanf("%d",&N);
	getnotation();
	P=0;
	int x,y,s;
	while(true){
		scanf("%d%d%d",&x,&y,&s);
		if(!(x||y||s)) break;
		P++;
		pn[P]=notation[x][y];
		ps[P]=s;
	};
}
int main(){
	freopen("lighthouse.in","r",stdin);
	freopen("lighthouse.out","w",stdout);
	init();
	solve();
	return 0;
}