比赛 NOIP模拟赛by mzx Day1 评测结果 AAAAAAAAAA
题目名称 昆特-冠位指定 最终得分 100
用户昵称 前鬼后鬼的守护 运行时间 1.520 s
代码语言 C++ 内存使用 2.25 MiB
提交时间 2016-10-20 21:47:14
显示代码纯文本
#include<cstdio>
#include<cstring>
#include<vector>
#include<algorithm>
#define FILE "gwent_grandorder"
namespace IO{
	char buf[1<<15],*fs,*ft;
	inline char gc(){return (fs==ft&&(ft=(fs=buf)+fread(buf,1,1<<15,stdin),fs==ft))?0:*fs++;}
	inline int read(){
		int x=0,rev=0,ch=gc();
		while(ch<'0'||ch>'9'){if(ch=='-')rev=1;ch=gc();}
		while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+ch-'0';ch=gc();}
		return rev?-x:x;
	}
}using namespace IO;

const int MAXN(100005);

int n,m,K;

struct Card{
	int v,ty,pos;
	int pow,spy;
}c[MAXN];

inline bool operator<(const Card& a,const Card& b){
	if(a.v!=b.v)return a.v<b.v;
	else if(a.ty!=b.ty)return a.ty<b.ty;
	else if(a.pos!=b.pos)return a.pos<b.pos;
	else if(a.pow!=b.pow)return a.pow<b.pow;
	else return a.spy<b.spy;
}

struct BattleField{
	bool weather[4];
	bool horn[2][4];
	int sum[2];
	inline int evaluate(int o,int pos,int pow){
		if(pos==4){
			int x=evaluate(o,1,pow),y=evaluate(o,2,pow);
			return !o?std::max(x,y):std::min(x,y);
		}
		else if(pos>=1&&pos<=3){
			if(weather[pos]&&pow>=1)
				pow=1;
			if(horn[o][pos])
				pow*=2;
		}
		return pow;
	}
}orgin;
int oS;

std::vector<int> e[2][6];

void init(){
	n=read(),m=read(),K=read();
	for(int i=1;i<=m;i++){
		int v=read(),ty=read(),pos=read();v++;
		if(ty==1||ty==3){
			if(ty==3)pos=5;
			int pow=read(),spy=read();
			e[spy][pos].push_back(pow);
		}
		else{
			if(pos==0)orgin.horn[1][read()]=true;
			else if(pos==4)
				orgin.weather[2]=orgin.weather[3]=true;
			else if(pos==5)
				memset(orgin.weather,0,sizeof orgin.weather);
		}
	}
	if(orgin.weather[1])
		oS|=1;
	if(orgin.weather[2])
		oS|=2;
	if(orgin.weather[3])
		oS|=4;
	for(int i=1;i<=n;i++){
		c[i].v=read();c[i].ty=read();c[i].pos=read();
		if(c[i].ty==1||c[i].ty==3){
			c[i].pow=read();
			c[i].spy=read();
		}
	}
	std::sort(c+1,c+n+1);
}

std::vector<int> u[2][6];
int cur[2][6],pw[2][6];
int skill[6];
int mns[1<<6];

int fmax(){
	int pos=0,mxp=0;
	for(int i=1;i<=5;i++)
		if(pw[0][i]>mxp)
			mxp=pw[0][i],pos=i;
	return pos;
}
int fmin(){
	int pos=0,mnp=int(2e4);
	for(int i=1;i<=5;i++)
		if(pw[0][i]<mnp)
			mnp=pw[1][i],pos=i;
	return pos;
}

bool Judge(int S,int cnt){
	BattleField now=orgin;
	for(int i=0;i<3;i++){
		now.weather[i+1]=S&(1<<i);
		now.horn[0][i+1]=S&(1<<(i+3));
	}
	for(int j=1;j<=5;j++)
		for(int i=0;i<2;i++)
			cur[i][j]=0,pw[i][j]=now.evaluate(i,j,u[i][j][0]);
	for(int k=0;k<2;k++)
		for(int i=1;i<=5;i++)
			for(int j=0,tot=int(e[k][i].size());j<tot;j++)
				now.sum[k^1]+=now.evaluate(k^1,i,e[k][i][j]);
	for(int i=1;i<=cnt;i++){
		int pos=fmax();
		if(pos==0)break;
		else{
			now.sum[0]+=pw[0][pos];
			pw[0][pos]=now.evaluate(0,pos,u[0][pos][++cur[0][pos]]);
		}
	}
	while(true){
		int pos[2];
		pos[0]=fmax();pos[1]=fmin();
		if(pos[0]==0||pos[1]==0||pw[0][pos[0]]<pw[1][pos[1]])break;
		else{
			for(int i=0;i<2;i++){
				now.sum[i]+=pw[i][pos[i]];
				pw[i][pos[i]]=now.evaluate(i,pos[i],u[i][pos[i]][++cur[i][pos[i]]]);
			}
		}
	}
	return now.sum[0]>now.sum[1];
}

void dfs(int now=0,int nS=oS,int cost=0){
	static int sS[5]={0,1,2,4,6};
	if(now==8){
		if(mns[nS]==-1||cost<mns[nS])
			mns[nS]=cost;
		return;
	}
	if(now==0&&skill[5])
		dfs(now+1,nS&(7<<3),cost+1);
	for(int i=1;i<=4;i++)
		if(now==i&&skill[i])
			dfs(now+1,nS|sS[i],cost+1);
	for(int i=5;i<=7;i++)
		if(now==i&&skill[0]){
			skill[0]--;
			dfs(now+1,nS|(1<<(i-2)),cost+1);
			skill[0]++;
		}
	dfs(now+1,nS,cost);
}
inline bool mycmp(int a,int b){
	return a>b;
}
bool Check(int x){
	for(int i=0;i<2;i++)
		for(int j=1;j<6;j++)
			u[i][j].clear();
	memset(skill,0,sizeof skill);
	memset(mns,-1,sizeof mns);
	for(int i=1;i<=x;i++){
		if(c[i].ty==2)
			skill[c[i].pos]++;
		else{
			int pos=c[i].pos;
			if(c[i].ty==3)pos=5;
			u[c[i].spy][pos].push_back(c[i].pow);
		}
	}
	for(int i=1;i<=5;i++){
		u[0][i].push_back(-1);
		std::sort(u[0][i].begin(),u[0][i].end(),mycmp);
	}
	for(int i=1;i<=5;i++){
		u[1][i].push_back(1e9);
		std::sort(u[1][i].begin(),u[1][i].end());
	}
	dfs();
	for(int S=0;S<(1<<6);S++)
		if(mns[S]!=-1&&Judge(S,K-mns[S]))
			return true;
	return false;
}

void binary(){
	int left=0,right=n+1;
	while(left!=right){
		int mid=(left+right)>>1;
		if(Check(mid))right=mid;
		else left=mid+1;
	}
	if(right==n+1)printf("SingleDogMZX\n");
	else printf("%d\n",c[left].v);
}

int main(){
	freopen(FILE".in","r",stdin);
	freopen(FILE".out","w",stdout);
	init();
	binary();
	return 0;
}