noip模拟40

A. 送花

首先当右端点右移时最优坐决策点不是单调的,因为加入一个数后可能使一个之前位置的贡献变小,那么原来依赖其贡献的最优区间可能左端点左移更优

线段树维护区间的贡献

对于右端点右移一位的时候,将这个值上上一个位置到上一个位置的值加当前贡献,上一个位置到这个位置的值减当前贡献,然后线段树维护区间最大值即可


B. 星空

首先是距离的转化,先把坐标系


C. 零一串

代码实现
#include<bits/stdc++.h>
using namespace std;
#define int long long
deque<int>q;
const int maxn=1e7+5;
const int mod=998244353;
char c[maxn];
int t,n,pos[maxn],cnt,all,dis[maxn],cf[maxn],sum[maxn],ans,num,ori;
bool ans1[maxn];
int po(int a,int b){
	int ans=1;
	while(b){
		if(b&1)ans=1ll*ans*a%mod;
		a=1ll*a*a%mod;
		b>>=1;
	}
	return ans;
}
signed main(){
//	freopen("shuju.in","r",stdin);
//	freopen("my.out","w",stdout);
	cin>>t;
	scanf("%s",c+1);
	n=strlen(c+1);
	for(int i=1;i<=n;i++){
		if(c[i]==‘1‘)num++;
		else ori+=num;
	}
	ori%=mod;
	for(int i=1;i<=n;i++){
		if(c[i]==‘1‘)pos[++cnt]=i;
	}
	for(int i=1;i<=t;i++){
		q.push_back(i);
	}
	for(int k=1;k<=cnt;k++){
		all++;
		if(q.back()+all>t&&q.size())q.pop_back();
		q.push_front(1-all);
		
		for(int j=1;j<=pos[k]-pos[k-1]-1&&q.size();j++){
			cf[q.front()+all]++;
			cf[min(cnt-k+q.front()+all+1,t+1)]--;
			q.pop_front();
		}
		
		dis[k]=t-q.size();
		ans1[pos[k]-dis[k]]=1;
	}
	for(int i=0;i<=t;i++){
		if(i)sum[i]=(sum[i-1]+cf[i])%mod;
		ori+=sum[i];
		ori%=mod;
		ans^=(po(233,i)*ori%mod);
	}
	for(int i=1;i<=n;i++)cout<<ans1[i];
	cout<<endl<<ans;
	return 0;
}

noip模拟40

上一篇:logback配置


下一篇:EF+VUE