Loading

noip模拟18

A. 导弹袭击

维护凸包的模板题,卡卡精度就行了.

A_code
#include<bits/stdc++.h>
using namespace std;
namespace BSS {
	#define ll long long int
	#define ull unsigned ll
	#define lf double
	#define lbt(x) (x&(-x))
	#define mp(x,y) make_pair(x,y)
	#define lb lower_bound 
	#define ub upper_bound
	#define Fill(x,y) memset(x,y,sizeof x)
	#define Copy(x,y) memcpy(x,y,sizeof x)
	#define File(x) freopen(#x".in","r",stdin),freopen(#x".out","w",stdout)
	inline ll read() {
		ll res=0; bool cit=1; char ch;
		while(!isdigit(ch=getchar())) if(ch=='-') cit=0; 
		while(isdigit(ch)) res=(res<<3)+(res<<1)+(ch^48),ch=getchar();
		return cit?res:-res;
	}
} using namespace BSS;

const ll N=3e5+21;
ll m,n;
ll stk[N],ans[N];
struct I { ll a,b,id; } p[N],bin[N];
vector<I> vec;
map<pair<ll,ll>,bool> vis;
inline bool cmp1(I i,I j){
if(i.a!=j.a) return i.a<j.a;
if(i.b!=j.b) return i.b<j.b;
return i.id<j.id;
}
inline bool cmp2(I i,I j){
	if(i.a!=j.a) return i.a>j.a;
	if(i.b!=j.b) return i.b<j.b;
	return i.id<j.id;
}
inline lf slope(ll i,ll j){ return 1.0*bin[i].a*bin[j].a*(bin[i].b-bin[j].b)/(1.0*bin[i].b*bin[j].b*(bin[i].a-bin[j].a)); }
signed main(){
	n=read(); ll l=1,r=0,cnt=0;
	for(int i=1;i<=n;i++){
		p[i].a=read(),p[i].b=read(),p[i].id=i;
	}
	sort(p+1,p+1+n,cmp1);
	for(int i=1;i<=n;i++){
		while(cnt and bin[cnt].a<=p[i].a and bin[cnt].b<=p[i].b)cnt--;
		bin[++cnt]=p[i];
	}
	sort(bin+1,bin+1+cnt,cmp2);	
	for(int i=1;i<=cnt;i++){
		while(l<r and slope(stk[r],stk[r-1])>slope(i,stk[r])) r--;
		stk[++r]=i;
	}
	for(int i=1;i<=r;i++){
		vis[mp(bin[stk[i]].a,bin[stk[i]].b)]=1;
	}
	sort(p+1,p+1+n,[](I i,I j)->bool{ return i.id<j.id; });	
	for(int i=1;i<=n;i++){
		if(vis.find(mp(p[i].a,p[i].b))!=vis.end()) printf("%lld ",p[i].id);
	}
	exit(0);
}

B. 炼金术士的疑惑

一个高斯消元板子.

B_code
#include<bits/stdc++.h>
using namespace std;
#define ll long long int
#define re register ll 
#define lf double
#define mp make_pair
#define le strlen
const ll N=300;
const ll p=1e6+3;
const ll mod=1e9+7;
inline void read(ll &ss)
{
	ss=0; bool cit=0; char ch;
	while(!isdigit(ch=getchar())) if(ch=='-') cit=1;
	while(isdigit(ch)) ss=(ss<<3)+(ss<<1)+(ch^48),ch=getchar();
	if(cit) ss=-ss;
}
map<string,ll> maps;
ll n,m,xs;
ll x[N];
lf a[N][N],H[N];
char s[N];
signed main()
{
//	freopen("0.in","r",stdin);
//	freopen("out","w",stdout);
	read(n); lf ff,tmp; ll len,temp,flag; char ch;
	for(re i=1;i<=n;i++)
	{
		ff=1;
		for(;1;)
		{
			scanf("%lf",&tmp); scanf("%s",s); 
			if(!maps[s]) maps[s]=++xs;
			a[i][maps[s]]=tmp*ff;
			scanf("%s",s+1); if(s[1]=='=') break;
		}
		ff=-1;
		for(;1;)
		{
			scanf("%lf",&tmp); scanf("%s",s); 
			if(!maps[s]) maps[s]=++xs;
			a[i][maps[s]]=tmp*ff;
			scanf("%s",s+1);
			if(s[1]=='H' and s[2]=='=') break;
		}
		scanf("%lf",&H[i]); // 已经乘过负号 !!
	}
	ff=1;
	for(;1;)
	{
		scanf("%lf",&tmp); scanf("%s",s); 
		if(!maps[s]) maps[s]=++xs;
		a[n+1][maps[s]]=tmp*ff;
		scanf("%s",s+1); if(s[1]=='=') break;
	}
	ff=-1;
	for(;1;)
	{
		scanf("%lf",&tmp); scanf("%s",s); 
		if(!maps[s]) maps[s]=++xs;
		a[n+1][maps[s]]=tmp*ff;
		scanf("%s",s+1);
		if(s[1]=='H' and s[2]=='=') break;
	}
	scanf("%s",s+1); xs++; m=xs;
	for(re i=1;i<=n;i++) a[i][xs]=-H[i];
	for(re i=1,j=1;i<=n,j<=m-1;i++,j++)
	{
		flag=i;
		for(re k=i+1;k<=n;k++)
			if(fabs(a[k][j])>fabs(a[flag][j])) 
				flag=k;
		if(flag!=i)
			for(re k=1;k<=m;k++)
				swap(a[i][k],a[flag][k]);
		if(!a[i][j]) { i--; continue; }
		for(re k=i+1;k<=n+1;k++)
		{
			if(!a[k][j]) continue;
			tmp=a[k][j]/a[i][j];
			for(re h=j;h<=m;h++)
				a[k][h]=a[k][h]-tmp*a[i][h];
		}
	}
	printf("%.1lf",a[n+1][m]+1e-12);
	return 0;
}	

/*
2
1 C + 1 O2 = 1 CO2 H= -393.5
1 CO + 0.5 O2 = 1 CO2 H= -283.0
2 C + 1 O2 = 2 CO H= ?

-221.0

 */

C. 老司机的狂欢

首先是两个明显的想法:二分答案和LIS
第一问很简单,然后考虑如何做第二问.
第一关键为长度,第二关键为字典序,
于是我们选择在同一长度下转移字典序最小,
可以想象成把所有以 \(1\)~\(n\) 的数字结尾的最优链都接到一棵类似于Trie树的树上,
然后树状数组转移即可,另外\(st\)表优化..

C_code
#include<bits/stdc++.h>
using namespace std;
namespace BSS
{
	#define ll long long int
	#define ull unsigned ll 
	#define re register ll 
	#define lf double
	#define lb lower_bound 
	#define ub upper_bound 
	#define mp make_pair
	#define lbt(x) (x&(-x))
	#define File(x,y) freopen(#x,"r",stdin),freopen(#y,"w",stdout)
	#define Fill(x,y) memset(x,y,sizeof x);
	#define Copy(x,y) memcpy(x,y,sizeof x);
	inline ll read()
	{
		ll ss=0; bool cit=1; char ch;
		while(!isdigit(ch=getchar())) if(ch=='-') cit=0;
		while(isdigit(ch)) ss=(ss<<3)+(ss<<1)+(ch^48),ch=getchar();
		return cit?ss:-ss;
	}
} using namespace BSS;

const ll N=1e5+21;

ll m,n,cnt,ans;
ll pt[N],lsh[N];
ll fa[N][25],st[N][25];
struct I { ll x,a,id; } p[N];
struct Bit{
	ll res; ll c[N<<3];
	inline void update(ll x,ll w){
		while(x<=cnt) c[x]=max(c[x],w),x+=lbt(x);
	}
	inline ll query(ll x){
		res=0;
		while(x>0) res=max(res,c[x]),x-=lbt(x);
		return res;	
	}
	inline void clr(){
		res=cnt<<1;
		for(re i=1;i<=res;++i) c[i]=0;
	}
}bit;
inline bool comp(I i,I j){ return i.x<j.x; }
inline void check(ll t){
	bit.clr(),cnt=0; ll tmp,temp;
	for(re i=1;i<=n;++i)
		lsh[++cnt]=(p[i].x<<1)+p[i].a*t*t;
	sort(lsh+1,lsh+1+cnt),cnt=unique(lsh+1,lsh+1+cnt)-lsh-1;
	for(re i=1;i<=n;++i){
		tmp=lb(lsh+1,lsh+1+cnt,(p[i].x<<1)+p[i].a*t*t)-lsh;
		temp=bit.query(tmp-1)+1,bit.update(tmp,temp);
	}
}
inline void ins(ll x,ll dad){
	fa[x][0]=st[x][0]=dad;
	for(re i=1;i<=20;++i){
		fa[x][i]=fa[fa[x][i-1]][i-1],
		st[x][i]=min(st[x][i-1],st[fa[x][i-1]][i-1]);
	}
}
inline bool Check(pair<ll,ll> x,pair<ll,ll> y){
	if(x.first!=y.first) return x.first<y.first;
	ll ansx=x.second,idx=x.second,ansy=y.second,idy=y.second;
	for(re i=20;i>=0;i--){ 
		if(fa[idx][i]!=fa[idy][i]){
			ansx=min(ansx,st[idx][i]),ansy=min(ansy,st[idy][i]),
			idx=fa[idx][i],idy=fa[idy][i];
		}
	}
	return ansx>ansy;
}
struct Bit_array{
	pair<ll,ll> c[N<<3]; pair<ll,ll> res;
	void update(ll x,pair<ll,ll> w){
		while(x<=cnt){
			if(Check(c[x],w)) c[x]=w;
			x+=lbt(x);
		}
	}
	pair<ll,ll> query(ll x){
		res=mp(0,0);
		while(x>0){
			if(Check(res,c[x])) res=c[x];
			x-=lbt(x);
		}
	//	cout<<res.first<<" "<<res.second<<"\n";
		return res;
	}
}biy;
signed main(){
	n=read(),m=read(); ll tmp; pair<ll,ll> temp;
	for(re i=1;i<=n;i++) p[i].x=read(),p[i].a=read(),p[i].id=i;
	sort(p+1,p+1+n,comp);
	ll le=0,ri=86400,mid; ans=0;
	while(le<=ri){
		mid=(le+ri)>>1,check(mid);
		if(bit.query(cnt)>=m) ans=mid,le=mid+1;
		else ri=mid-1;
	}
	printf("%lld\n",ans); check(ans);
	if(bit.query(cnt)>m) puts("-1"),exit(0);
	for(re i=1;i<=n;i++){
		tmp=lb(lsh+1,lsh+1+cnt,(p[i].x<<1)+p[i].a*ans*ans)-lsh,
		temp=biy.query(tmp-1),ins(p[i].id,temp.second),
		biy.update(tmp,mp(temp.first+1,p[i].id));
	}
	tmp=biy.query(cnt).second;
//	cout<<biy.query(cnt).first<<' '<<biy.query(cnt).second<<endl;
	for(re i=1;i<=m;i++) pt[i]=tmp,tmp=fa[tmp][0];
	sort(pt+1,pt+1+m);
	for(re i=1;i<=m;i++) printf("%lld\n",pt[i]);
	exit(0);
}
posted @ 2021-08-05 19:53  AaMuXiiiiii  阅读(33)  评论(0编辑  收藏  举报