【2020省选模拟】题解

T1

线段树优化建图后强联通缩点再跑个拓扑排序求一个是否必要即可
用堆维护一下分量内的值

#include<bits/stdc++.h>
using namespace std;
#define cs const
#define pb push_back
#define pii pair<int,int>
#define fi first
#define bg begin
#define se second
#define ll long long
cs int RLEN=1<<20|1;
inline char gc(){
	static char ibuf[RLEN],*ib,*ob;
	(ib==ob)&&(ob=(ib=ibuf)+fread(ibuf,1,RLEN,stdin));
	return (ib==ob)?EOF:*ib++;
}
inline int read(){
	char ch=gc();
	int res=0;bool f=1;
	while(!isdigit(ch))f^=ch=='-',ch=gc();
	while(isdigit(ch))res=(res*10)+(ch^48),ch=gc();
	return f?res:-res;
}
template<typename tp>inline void chemx(tp &a,tp b){a=max(a,b);}
template<typename tp>inline void chemn(tp &a,tp b){a=min(a,b);}
cs int N=100005,M=600005;
char xxx;
int adj[M],nxt[M<<1],to[M<<1],ecnt;
inline void addedge(int u,int v){
	nxt[++ecnt]=adj[u],adj[u]=ecnt,to[ecnt]=v;
}
int n,m,tot;
struct node{
	int p,r,c,id;
	friend inline bool operator <(cs node &a,cs node &b){
		return a.p<b.p;
	}
}p[N];
namespace Seg{
	int id[M];
	#define lc (u<<1)
	#define rc ((u<<1)|1)
	#define mid ((l+r)>>1)
	void build(int u,int l,int r){
		id[u]=++tot;
		if(l==r){addedge(id[u],l);return;}
		build(lc,l,mid),build(rc,mid+1,r);
		addedge(id[u],id[lc]),addedge(id[u],id[rc]);
	}
	void link(int u,int l,int r,int st,int des,int k){
		if(st<=l&&r<=des)return addedge(k,id[u]);
		if(st<=mid)link(lc,l,mid,st,des,k);
		if(mid<des)link(rc,mid+1,r,st,des,k);
	}
	#undef lc
	#undef rc
	#undef mid
}
int ps[N],tp[N];
int tim,belnum,bel[M],dfn[M],low[M],stk[M],top,vis[M],d[M],is_t[M],cov[M];
vector<int> E[M];
inline void topsort(){
	queue<int> q;
	for(int i=1;i<=belnum;i++)if(!d[i])q.push(i);
	while(q.size()){
		int u=q.front();q.pop();
		for(int i=0;i<E[u].size();i++){
			int v=E[u][i];
			cov[v]|=is_t[u]|cov[u];
			d[v]--;if(!d[v])q.push(v);
		}
	}
}
void tarjan(int u){
	dfn[u]=low[u]=++tim,vis[u]=1,stk[++top]=u;
	for(int v,e=adj[u];e;e=nxt[e]){
		v=to[e];
		if(!dfn[v])tarjan(v),chemn(low[u],low[v]);
		else if(vis[v])chemn(low[u],dfn[v]);
	}
	if(low[u]>=dfn[u]){
		int tmp;belnum++;
		do{
			tmp=stk[top--],vis[tmp]=0;
			bel[tmp]=belnum,is_t[belnum]|=tmp<=n;
		}while(tmp!=u);
	}
}
int trp[M],numb;
struct heap{
	priority_queue<int,vector<int>,greater<int> >a,b;
	inline void push(int x){a.push(x);}
	inline void erase(int x){b.push(x);}
	inline int size(){return a.size()-b.size();}
	inline int top(){
		while(b.size()&&a.top()==b.top())a.pop(),b.pop();
		return a.top();
	}
}qr[N];
char yyy;
int main(){
	tot=n=read();
	for(int i=1;i<=n;i++){
		p[i].p=read(),p[i].r=read(),p[i].c=read(),p[i].id=i;
	}sort(p+1,p+n+1);
	for(int i=1;i<=n;i++)tp[p[i].id]=i,ps[i]=p[i].p;
	Seg::build(1,1,n);
	for(int i=1;i<=n;i++){
		int l=lower_bound(ps+1,ps+n+1,p[i].p-p[i].r)-ps,
		r=upper_bound(ps+1,ps+n+1,p[i].p+p[i].r)-ps-1;
		Seg::link(1,1,n,l,r,i);
	}
	for(int i=1;i<=tot;i++)if(!dfn[i])tarjan(i);
	for(int i=1;i<=tot;i++)
	for(int j,e=adj[i];e;e=nxt[e]){
		j=to[e];
		if(bel[i]!=bel[j]){
			E[bel[i]].pb(bel[j]);d[bel[j]]++;
		}
	}ll ans=0;
	topsort();
	for(int i=1;i<=belnum;i++)if(!cov[i]&&is_t[i])trp[i]=++numb;
	for(int i=1;i<=n;i++)if(trp[bel[i]])qr[trp[bel[i]]].push(p[i].c);
	for(int i=1;i<=numb;i++){
		if(qr[i].size())ans+=qr[i].top();
	}
	m=read();
	while(m--){
		int u=tp[read()],id=trp[bel[u]],k=read();
		if(cov[bel[u]]){
			p[u].c=k;
			cout<<ans<<'\n';
			continue;
		}
		ans-=qr[id].top();
		qr[id].erase(p[u].c),p[u].c=k;
		qr[id].push(p[u].c);
		ans+=qr[id].top();
		cout<<ans<<'\n';
	}
	return 0;
}

T2:

利用回文串 l o g log log个等差数列的形式
然后 e x g c d exgcd exgcd算解的个数
由于每次最多只有 O ( l o g ) O(log) O(log)个有交
所以复杂度是两个 l o g log log

#include<bits/stdc++.h>
using namespace std;
#define cs const
#define pb push_back
#define pii pair<int,int>
#define fi first
#define bg begin
#define se second
#define ll long long
cs int RLEN=1<<20|1;
inline char gc(){
	static char ibuf[RLEN],*ib,*ob;
	(ib==ob)&&(ob=(ib=ibuf)+fread(ibuf,1,RLEN,stdin));
	return (ib==ob)?EOF:*ib++;
}
inline int read(){
	char ch=gc();
	int res=0;bool f=1;
	while(!isdigit(ch))f^=ch=='-',ch=gc();
	while(isdigit(ch))res=(res*10)+(ch^48),ch=gc();
	return f?res:-res;
}
inline int readstring(char *s){
	int top=0;char ch=gc();
	while(isspace(ch))ch=gc();
	while(!isspace(ch))s[++top]=ch,ch=gc();
	s[top+1]='\0';return top;
}
template<typename tp>inline void chemx(tp &a,tp b){a=max(a,b);}
template<typename tp>inline void chemn(tp &a,tp b){a=min(a,b);}
cs int N=100005;
char xxx;
struct node{
	int s,t,del;
	node(int a=0,int b=0,int c=0):s(a),t(b),del(c){}
}p[N][2][61];
int n,m,cnt[N][2];
char str[N];
struct Pam{
	int tot,cnt,nxt[N][27],fail[N],len[N],del[N],top[N],s[N],last;
	inline void init(){
		tot=1,fail[0]=1,len[1]=-1,s[0]=-1;
	}
	inline int find(int p,int k){
		while(s[k-len[p]-1]!=s[k])p=fail[p];return p;
	}
	inline void insert(int c,node *pt,int &ct){
		s[++cnt]=c;int p=find(last,cnt);
		if(!nxt[p][c]){
			fail[++tot]=nxt[find(fail[p],cnt)][c];
			nxt[p][c]=tot,len[tot]=len[p]+2;
			del[tot]=len[tot]-len[fail[tot]];
			if(del[tot]==del[fail[tot]])top[tot]=top[fail[tot]];
			else top[tot]=tot;
		}last=nxt[p][c];
		p=last;
		while(p>1){
			pt[++ct]=node(len[top[p]],len[p],del[p]),p=fail[top[p]];
			
		}
	}
}t1,t2;
char yyy;
inline int exgcd(int a,int b,int &x,int &y){
	if(b==0){x=1,y=0;return a;}
	int t=exgcd(b,a%b,y,x);
	y-=a/b*x;return t;
}
inline int solve(int a,int b,int la,int lb,int k){
	int x,y;int d=exgcd(a,b,x,y);
	if(k%d!=0)return 0;
	x*=k/d,y*=k/d;
	int db=b/d,da=a/d,mx=x%db;if(mx<0)mx+=db;
	y+=((x-mx)/db)*da;x=mx;
	if(y<0)return 0;
	if(y>lb){
		int ti=(y-lb-1)/da+1;
		y-=ti*da,x+=ti*db;
	}
	if(x>la||x<0||y>lb||y<0)return 0;
	int tt=min((la-x)/db+1,y/da+1);
	return tt;
}
inline int check(cs node &x,cs node &y,int len){
	return solve(x.del,y.del,(x.t-x.s)/x.del,(y.t-y.s)/y.del,len-x.s-y.s);
}
inline int query(node *l,int a,node *r,int b,int len){
	int res=0;
	for(int i=a;i&&l[i].s<=len;i--)
	for(int j=b;j&&r[j].s+l[a].s<=len;j--)
	if(l[i].t+r[j].t>=len)res+=check(l[i],r[j],len);
	return res;
}
int main(){
	n=read(),m=read();
	readstring(str);t1.init(),t2.init();
	for(int i=1;i<=n;i++)t1.insert(str[i]-'a',p[i][0],cnt[i][0]);
	for(int i=n;i>=1;i--)t2.insert(str[i]-'a',p[i][1],cnt[i][1]);
	while(m--){
	//cout<<m<<'\n';
		int l=read(),r=read();
		cout<<query(p[l][1],cnt[l][1],p[r][0],cnt[r][0],r-l+1)<<'\n';
	}return 0;
}

T3:

f , g [ i ] [ j ] [ k ] f,g[i][j][k] f,g[i][j][k]表示前 i i i行,选了 j j j块,删了 k k k个位置,当前行选/没选的最大值
考虑转移就相当于是
F k = max ⁡ x ( G x + P k − x ) F_k=\max_x(G_x+P_{k-x}) Fk=maxx(Gx+Pkx)这样的东西
而且 P P P是一个上凸壳的
那么如果某个时候 G 中 , i < j , j G中,i<j,j Gi<j,j i i i优,以后一定都优,因为 P P P递增的越来越慢

于是分治优化决策单调性 D P DP DP即可

http://192.168.110.251/problempage.php?problem_id=4917
#include<bits/stdc++.h>
using namespace std;
#define cs const
#define pb push_back
#define pii pair<int,int>
#define fi first
#define bg begin
#define se second
#define ll long long
cs int RLEN=1<<20|1;
inline char gc(){
	static char ibuf[RLEN],*ib,*ob;
	(ib==ob)&&(ob=(ib=ibuf)+fread(ibuf,1,RLEN,stdin));
	return (ib==ob)?EOF:*ib++;
}
inline int read(){
	char ch=gc();
	int res=0;bool f=1;
	while(!isdigit(ch))f^=ch=='-',ch=gc();
	while(isdigit(ch))res=(res*10)+(ch^48),ch=gc();
	return f?res:-res;
}
inline int readstring(char *s){
	int top=0;char ch=gc();
	while(isspace(ch))ch=gc();
	while(!isspace(ch))s[++top]=ch,ch=gc();
	s[top+1]='\0';return top;
}
template<typename tp>inline void chemx(tp &a,tp b){a=max(a,b);}
template<typename tp>inline void chemn(tp &a,tp b){a=min(a,b);}
cs int N=10005;
cs ll INF=-9187201950435737472;
ll f[2][4][N],g[2][4][N],p[N],tmp[N],*tg,*tp;
int n,m,A,B,a[N];
void DP(int l,int r,int ql,int qr){
	if(l>r)return;
	int mid=(l+r)>>1,ps=ql;
	ll mx=INF;
	for(int i=ql;i<=qr&&i<=mid;i++){
		ll vl=tg[i];
		if(mid-i<=m)vl+=tp[mid-i];
		if(vl>mx)mx=vl,ps=i;
	}
	chemx(tmp[mid],mx);
	DP(l,mid-1,ql,ps);
	DP(mid+1,r,ps,qr);
}
inline void trans(ll *ans,ll *_g,ll *_p){
	tg=_g,tp=_p;
	memset(tmp,128,sizeof(tmp));
	DP(0,A,0,A);
	for(int i=0;i<=A;i++)chemx(ans[i],tmp[i]);
}
int main(){
	#ifdef Stargazer
	freopen("lx.in","r",stdin);
	#endif
	n=read(),m=read(),A=read(),B=read();
	memset(f[0],128,sizeof(f[0]));
	memset(g[0],128,sizeof(g[0]));
	g[0][0][0]=0;
	int cur=0;
	for(int tt=1;tt<=n;tt++){
		p[0]=0;cur^=1;
		memset(f[cur],128,sizeof(f[cur]));
		memset(g[cur],128,sizeof(g[cur]));
		for(int i=1;i<=m;i++)a[i]=read(),p[0]+=a[i];
		sort(a+1,a+m+1);
		for(int i=1;i<=m;i++)p[i]=p[i-1]-a[i];
		for(int j=0;j<=B;j++)
		for(int k=0;k<=A;k++)g[cur][j][k]=max(f[cur^1][j][k],g[cur^1][j][k]);
		for(int i=0;i<=B;i++)trans(f[cur][i],f[cur^1][i],p);
		for(int i=1;i<=B;i++)trans(f[cur][i],g[cur^1][i-1],p);
	}ll res=INF;
	for(int i=0;i<=B;i++)
	for(int j=0;j<=A;j++)chemx(res,max(f[cur][i][j],g[cur][i][j]));
	cout<<res<<'\n';return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。
1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值