为什么开O2 95分 不开O2 100分?
  • 板块学术版
  • 楼主c201904
  • 当前回复4
  • 已保存回复4
  • 发布时间2020/11/19 15:33
  • 上次更新2023/11/5 07:44:06
查看原帖
为什么开O2 95分 不开O2 100分?
50945
c201904楼主2020/11/19 15:33

代码如下:

#include<bits/stdc++.h>
using namespace std;
#define ll long long
const int N=2e6+5;
int read(){
	int b=0;
	char x=getchar();
	while(x<'0'||x>'9')x=getchar();
	while(x>='0'&&x<='9'){
		b=(b<<3)+(b<<1)+(x-'0');
		x=getchar();
	}
	return b;
}
int n;
int c[N],a[N],vis[N];
struct node{
	int id;
	bool operator >(const node&rhs)const {return c[id]!=c[rhs.id]?c[id]>c[rhs.id]:id>rhs.id;}
};
struct Node{
	int l,r,q[N];//l为队头 
	inline int size(){return r-l+1;}
	inline void pop_front(){l++;}
	inline void push_front(int x){q[--l]=x;}
	inline void pop_back(){r--;}
	inline void push_back(int x){q[++r]=x;}
	inline int front(){return q[l];}
	inline int back(){return q[r];}
}q,q1;
int g[N];
int top(int op){
	int x,y;
	//if(!(q.size()+q1.size()))return -1;//保证不会 
	if(!q.size()){
		x=q1.front();
		if(op)q1.pop_front();
		return x;
	}
	if(!q1.size()){
		x=q.front();
		if(op)q.pop_front();
		return x;
	}
	x=q.front(),y=q1.front();
	if((node){x}>(node){y}){		
		if(op)q.pop_front();
		return x;
	}
	else {		
		if(op)q1.pop_front();
		return y;
	}
}
int ans;
int l,pla,panda;
int getmin(){
	if(!pla){
		++l;
		q.pop_back();
		return l-1;
	}
	if(!q.size()){
		panda=1;
		q1.pop_back();
		return pla;
	}
	if((node){l}>(node){pla}){
		panda=1;
		q1.pop_back();
		return pla;
	}
	++l;q.pop_back();
	return l-1;
}
int eaten=0;
int solve(){
	int t=a[n];
	for(int i=1;i<n;i++){
		t-=a[i];
		if(t<0)break;
	}
	
	if(t>=0)return 1;
	q.l=q1.l=1;q.r=q1.r=0;
	for(int i=1;i<=n;i++)c[i]=a[i];
	for(int i=n;i>=1;i--)q.push_back(i);
	int tot=0;
	l=1;pla=0;ans=0;eaten=0;
	while(1){		
		if(eaten==(n-2))return 3;
		int u=top(1),nxt=top(0),v;//每个u都必须吃一个
		do{
			panda=0;v=getmin();
			c[u]-=c[v];
			eaten++;
			if(panda){
				eaten--;
				ans=n-g[v]+1;
				c[u]+=c[v];q1.push_front(u);//当做v还没被吃掉 
				break;
			}
		}while((node){u}>(node){nxt});
		if(!ans)q1.push_back(u);
		else break;
		//后推进来的一定比先推进来的小(吃的比它大,吃之前还剩的少些) 
		g[u]=l-1;pla=u;
	}	
	while(1){//找到最后一个敢吃的(若其fa不敢吃,则其敢吃) 
		int u=top(1),v=pla;
		//一旦一个l成为了最小了,那么之前那个(吃的蛇)就永远不再会成为最小
		tot++; eaten++;
		if(eaten==(n-3))return ans-(!(tot&1));//3吃了后2一定不能吃 
		c[u]-=c[v];pla=u;
		if(q.size()&&( (node){u}>(node){q.back()}) ){
		//	cout<<tot<<" ";
			return ans-(!(tot&1));
		}
		if(q1.size()&&( (node){u}>(node){q1.back()}) ){
		//	cout<<tot<<endl;
			return ans-(!(tot&1));
		}
		
	}

	return ans;
}
int cases;
int main(){
//	freopen("snakes20.in","r",stdin);
	
	scanf("%d",&cases);
	scanf("%d",&n);
	for(int i=1;i<=n;i++)a[i]=read();
	cases--;
	int A=solve();
	cout<<A<<endl;
	for(int t=1;t<=cases;t++){
		int k;
		scanf("%d",&k);
		for(int i=1;i<=k;i++){
			int xx=read();
			a[xx]=read();
		}
		int x=solve();
		cout<<x<<endl;		
	}
	return 0;
}
2020/11/19 15:33
加载中...