• 202289 #24 CF1408H & CF1696G & AGC043F


    摆。

    有同学给我推荐了音游,玩了一下,非常好玩啊!(所以这就是你不更博的理由吗

    060 CF1408H Rainbow Triples

    第一眼就可以想到一个网络流模型:将 \(0\) 向后面的 \(b_i\) 连边,\(b_i\) 向后面的 \(0\) 连边。问题在于怎么钦定哪些 \(0\) 连入,哪些 \(0\) 连出。

    由于答案上界是 \(0\) 的数量 \(z\) 除二,可以钦定前一半 \(0\) 连入,后一半 \(0\) 连出,显然仍然正确。

    对于一种颜色,我们找到这个颜色最靠前、最靠后的两个位置 \(u,v\),于是我们可以将连边刻画成 \(S\rightarrow c,c\rightarrow[1,\min(u,\lfloor\frac z2\rfloor)],c\rightarrow [\max(v,\lceil\frac z2\rceil)+1,z]\)

    前缀后缀连边可以使用前缀和,令前一半的 \(0\) 从后往前连边,后一半的 \(0\) 从前往后连边,那么问题就变成了求这张图的最大流。

    最大流转最小割,于是一个颜色不割,就要割对应的前缀和后缀所有点。

    从后往前枚举前缀割了多长,用线段树维护每个后缀割的长度对应答案,复杂度 \(O(n\log n)\)

    #include<stdio.h>
    #include<vector>
    #define lc(x) (x<<1)
    #define rc(x) (x<<1|1)
    #define mid (l+r>>1)
    using namespace std;
    const int maxn=500005,maxt=maxn<<2;
    int T,n,z,ans;
    int a[maxn],l[maxn],r[maxn],lazy[maxt],mn[maxt];
    vector<int>v[maxn];
    inline void pushup(int now){
    	mn[now]=min(mn[lc(now)],mn[rc(now)]);
    }
    inline void getlazy(int now,int v){
    	lazy[now]+=v,mn[now]+=v;
    }
    inline void pushdown(int now){
    	if(lazy[now])
    		getlazy(lc(now),lazy[now]),getlazy(rc(now),lazy[now]),lazy[now]=0;
    }
    void build(int l,int r,int now){
    	lazy[now]=0;
    	if(l==r){
    		mn[now]=l+n;
    		return ;
    	}
    	build(l,mid,lc(now)),build(mid+1,r,rc(now)),pushup(now);
    }
    void update(int l,int r,int now,int L,int R,int v){
    	if(L<=l&&r<=R){
    		getlazy(now,v);
    		return ;
    	}
    	pushdown(now);
    	if(L<=mid)
    		update(l,mid,lc(now),L,R,v);
    	if(mid<R)
    		update(mid+1,r,rc(now),L,R,v);
    	pushup(now);
    }
    int main(){
    	scanf("%d",&T);
    	while(T--){
    		scanf("%d",&n),z=0;
    		for(int i=1;i<=n;i++)
    			scanf("%d",&a[i]),z+=a[i]==0;
    		for(int i=1;i<=n;i++)
    			l[i]=r[i]=0;
    		int now=0;
    		for(int i=1;i<=n;i++){
    			if(a[i]==0)
    				now++;
    			else if(now<=z/2)
    				l[a[i]]=max(l[a[i]],now);
    		}
    		now=0;
    		for(int i=n;i>=1;i--){
    			if(a[i]==0)
    				now++;
    			else if(now<=z/2)
    				r[a[i]]=max(r[a[i]],now);
    		}
    		build(0,z/2,1);
    		for(int i=1;i<=n;i++)
    			v[l[i]].push_back(r[i]);
    		ans=1e9;
    		for(int i=0;i<=z/2;i++){
    			for(int j=0;j<v[i].size();j++)
    				update(0,z/2,1,v[i][j],z/2,-1);
    			v[i].clear();
    			ans=min(ans,mn[1]+i);
    		}
    		printf("%d\n",min(z/2,ans));
    	}
    	return 0;
    }
    

    061 CF1696G Fishingprince Plays With Array Again

    之后再写。

    #include<stdio.h>
    #include<string.h>
    #include<iostream>
    #define lc(x) (x<<1)
    #define rc(x) (x<<1|1)
    #define mid (l+r>>1)
    using namespace std;
    const int maxn=200005,maxt=maxn<<2; 
    int n,m,x,y;
    int a[maxn];
    struct matrix{
    	int len,wid;
    	double a[4][4];
    	matrix operator *(matrix p){
    		matrix res;
    		res.len=len,res.wid=p.wid;
    		for(int i=1;i<=res.len;i++)
    			for(int j=1;j<=res.wid;j++)
    				res.a[i][j]=-1e18;
    		for(int i=1;i<=len;i++)
    			for(int j=1;j<=p.wid;j++)
    				for(int k=1;k<=wid;k++)
    					res.a[i][j]=max(res.a[i][j],a[i][k]+p.a[k][j]);
    		return res;
    	}
    }st,t[maxt],trans;
    inline void setval(int p,int now){
    	t[now].len=t[now].wid=3,t[now].a[1][1]=0,t[now].a[2][2]=1.0*a[p]/x,t[now].a[3][3]=1.0*a[p]/(x+y);
    }
    inline void pushup(int now){
    	t[now]=t[lc(now)]*trans*t[rc(now)];
    }
    void build(int l,int r,int now){
    	if(l==r){
    		setval(l,now);
    		return ;
    	}
    	build(l,mid,lc(now)),build(mid+1,r,rc(now)),pushup(now);
    }
    void modify(int l,int r,int now,int p){
    	if(l==r){
    		setval(l,now);
    		return ;
    	}
    	if(p<=mid)
    		modify(l,mid,lc(now),p);
    	else modify(mid+1,r,rc(now),p);
    	pushup(now);
    }
    matrix query(int l,int r,int now,int L,int R){
    	if(L<=l&&r<=R)
    		return t[now];
    	if(L<=mid&&mid<R)
    		return query(l,mid,lc(now),L,R)*trans*query(mid+1,r,rc(now),L,R);
    	if(L<=mid)
    		return query(l,mid,lc(now),L,R);
    	return query(mid+1,r,rc(now),L,R);
    }
    int main(){
    	st.len=1,st.wid=3;
    	trans.len=trans.wid=3,trans.a[2][2]=trans.a[2][3]=trans.a[3][2]=-1e18;//0 1/x 1/(x+y)
    	scanf("%d%d%d%d",&n,&m,&x,&y);
    	if(x<y)
    		swap(x,y);
    	for(int i=1;i<=n;i++)
    		scanf("%d",&a[i]);
    	build(1,n,1);
    	for(int i=1,t,x,y;i<=m;i++){
    		scanf("%d%d%d",&t,&x,&y);
    		if(t==1)
    			a[x]=y,modify(1,n,1,x);
    		if(t==2){
    			matrix res=st*query(1,n,1,x,y);
    			double ans=0;
    			for(int i=1;i<=3;i++)
    				ans=max(ans,res.a[1][i]);
    			printf("%.10lf\n",ans);
    		}
    	}
    	return 0;
    }
    

    062 AGC043F Jewelry Box

    之后再写。

    #include<stdio.h>
    #include<queue>
    #include<vector>
    #include<algorithm>
    #define inf 1000000000000000000
    #define INF 100000
    using namespace std;
    const int maxn=1005,maxm=10005;
    int n,m,Q,e=1,flow,tot,s,t;
    int start[maxn],to[maxm],then[maxm],limit[maxm],mn[maxn],vis[maxn],rec[maxn];
    int K[maxn],sum[maxn];
    long long cost;
    long long dis[maxn],worth[maxm],res[3][maxn];
    queue<int>q;
    inline void add(int x,int y,int z,long long w){
        then[++e]=start[x],start[x]=e,to[e]=y,limit[e]=z,worth[e]=w;
    }
    inline void addedge(int x,int y,int z,long long w){
    	add(x,y,z,w),add(y,x,0,-w);
    }
    int spfa(int s,int t){
    	for(int i=1;i<=t;i++)
    		dis[i]=inf,vis[i]=rec[i]=0;
    	while(!q.empty())
    		q.pop();
    	dis[s]=0,vis[s]=1,mn[s]=INF,q.push(s);
    	while(!q.empty()){
    		int x=q.front();
    		vis[x]=0,q.pop();
    		for(int i=start[x];i;i=then[i]){
    			int y=to[i];
    			long long z=worth[i];
    			if(limit[i]&&dis[y]>dis[x]+z){
    				dis[y]=dis[x]+z,rec[y]=i,mn[y]=min(mn[x],limit[i]);
    				if(vis[y]==0)
    					q.push(y),vis[y]=1;
    			}
    		}
    	}
    	return rec[t]!=0;
    }
    void work(int s,int t){
    	cost+=dis[t]*mn[t],flow+=mn[t];
    	for(int i=t;i!=s;i=to[rec[i]^1])
    		limit[rec[i]]-=mn[t],limit[rec[i]^1]+=mn[t];
    }
    struct jew{
    	long long s,c;
    	int p;
    	bool operator <(const jew &t)const{
    		return s<t.s||(s==t.s&&p<t.p);
    	}
    }w[maxn];
    int main(){
    	scanf("%d",&n);
    	for(int i=1,k;i<=n;i++){
    		scanf("%d",&k),sum[i+1]=sum[i]+k,K[i]=k;
    		for(int j=1;j<=k;j++)
    			scanf("%lld%d%lld",&w[sum[i]+j].s,&w[sum[i]+j].p,&w[sum[i]+j].c);
    		sort(w+sum[i]+1,w+sum[i]+k+1);
    	}
    	s=sum[n+1]+1,t=s+1;
    	for(int i=1;i<=n;i++){
    		int lst=s;
    		for(int j=1;j<=K[i];j++){
    			addedge(sum[i]+j,lst,INF,0),addedge(lst,sum[i]+j,INF,w[sum[i]+j].c);
    			addedge(lst,sum[i]+j,w[sum[i]+j].p,0),lst=sum[i]+j;
    		}
    		addedge(sum[i]+K[i],t,INF,0),addedge(t,sum[i]+K[i],INF,0);
    	}
    	scanf("%d",&m);
    	for(int i=1,x,y,z;i<=m;i++){
    		scanf("%d%d%d",&x,&y,&z);
    		for(int j=sum[x]+1;j<=sum[x]+K[x];j++){
    			int p=lower_bound(w+sum[y]+1,w+sum[y]+K[y]+1,jew{w[j].s+z+1,0,0})-w;
    			if(p==sum[y]+1)
    				addedge(s,j,INF,0);
    			else addedge(p-1,j,INF,0);
    		}
    	}
    	while(spfa(s,t)){
    		tot++,res[0][tot]=dis[t],work(s,t),res[1][tot]=flow,res[2][tot]=cost;
    		if(flow>=INF)
    			break;
    	}
    	scanf("%d",&Q);
    	while(Q--){
    		long long x;
    		scanf("%lld",&x);
    		int p=(lower_bound(res[0]+1,res[0]+1+tot,x)-res[0]);
    		if(p>tot)
    			puts("-1");
    		else printf("%lld\n",x*res[1][p-1]-res[2][p-1]);
    	}
    	return 0;
    }
    
  • 相关阅读:
    flex 连接mysql
    正确配置调试world wind on vs2008
    FLex调用servlet连接数据库
    c# 连接mysql并webservice数据
    ADF连接SOM
    转载加收藏关于OPENGL配置VS2008
    flex不能显示本地发布的地图
    Symbian专区
    asp.net控件开发基础學習
    控制网页大小
  • 原文地址:https://www.cnblogs.com/xiaoziyao/p/16566166.html
Copyright © 2020-2023  润新知