SCOI2015 day1

来源:互联网 发布:java都能做什么 编辑:程序博客网 时间:2024/04/30 05:55
第二次做这套题了。。结果还是太naive
T1
一个矩阵 n*m,选出n个数并且不在同一行同一列
二份答案转换为判定问题,看看够不够k个
如果在一行在一列有冲突怎么解决呢?网络流经典模型!
如果一个符合要求,连接该点所在的行和列即可
最大流满流的话就是合法的答案
T2
当年觉得需要离散化呢,现在写一下发现是想多了
维护f[i][j],表示i个人向前2^j传到达的人
在环上?倍长!
边界有问题?加哨兵!
由于编号问题,makedata没写好导致炸0....下次注意
T3
考察0-1和i-i+1
对于一个点,如果这个点与0-1的面积比i-i+1小,我们称这个点为合法点
显然我们可以很简单的拿到2个合法点(连接0和i+1,在这条线上二分,1和i一样)
然后可以证明这两个点的连线的靠近0-1一侧都是合法点(证明可以作垂线然后相识做)

这样对于每个i-i+1都可以得到一条合法线,那么半平面交就OK

代码

T1

//Copyright(c)2016 liuchenrui#include<cstdio>#include<algorithm>#include<cstring>#define inf 1000000000using namespace std;inline void splay(int &v){v=0;char c=0;int p=1;while(c<'0' || c>'9'){if(c=='-')p=-1;c=getchar();}while(c>='0' && c<='9'){v=(v<<3)+(v<<1)+c-'0';c=getchar();}v*=p;}int a[255][255];struct Edge{int to,next,flow;}edge[1000010];int first[600],size;int deep[600],dl[600];void addedge(int x,int y,int z){size++;edge[size].to=y;edge[size].next=first[x];first[x]=size;edge[size].flow=z;}int dfs(int now,int flow,int aim){if(now==aim)return flow;int F=0;for(int u=first[now];u&&flow;u=edge[u].next){if(deep[edge[u].to]==deep[now]+1&&edge[u].flow){int tmp=dfs(edge[u].to,min(flow,edge[u].flow),aim);F+=tmp;edge[u].flow-=tmp;edge[u^1].flow+=tmp;flow-=tmp;}}if(!F)deep[now]=-5;return F;}bool bfs(int S,int T){memset(deep,0,sizeof(deep));dl[1]=S;deep[S]=1;int head=0,tail=1;while(head!=tail){int v=dl[++head];for(int u=first[v];u;u=edge[u].next){if(!deep[edge[u].to]&&edge[u].flow){dl[++tail]=edge[u].to;deep[edge[u].to]=deep[v]+1;}}}return deep[T];}int maxflow(int S,int T){int ret=0;while(bfs(S,T)){ret+=dfs(S,inf,T);}return ret;}int n,m,k;int check(int mid){memset(first,0,sizeof first);size=1;for(int i=1;i<=n;i++){for(int j=1;j<=m;j++){if(a[i][j]<=mid){addedge(i,j+250,1);addedge(j+250,i,0);}}}for(int i=1;i<=n;i++){addedge(0,i,1);addedge(i,0,0);}for(int j=1;j<=m;j++){addedge(j+250,550,1);addedge(550,j+250,0);}int tmp=maxflow(0,550);return tmp;}int main(){freopen("matrix.in","r",stdin);freopen("matrix.out","w",stdout);splay(n),splay(m),splay(k);k=n-k+1;for(int i=1;i<=n;i++){for(int j=1;j<=m;j++){splay(a[i][j]);}}int l=0,r=1000000009;while(l!=r){int mid=l+r>>1;if(check(mid)<k)l=mid+1;else r=mid;}printf("%d\n",l);}

T2

//Copyright(c)2016 liuchenrui#include<cstdio>#include<ctime>#include<iostream>#include<algorithm>#include<cstring>using namespace std;inline void splay(int &v){v=0;char c=0;int p=1;while(c<'0' || c>'9'){if(c=='-')p=-1;c=getchar();}while(c>='0' && c<='9'){v=(v<<3)+(v<<1)+c-'0';c=getchar();}v*=p;}struct SCOI2015{int l,r;int id;}s[200010],e[200010];int Ans[200010];bool comp(const SCOI2015 &a,const SCOI2015 &b){return a.l<b.l;}bool in(int now,int l,int r){if(now==1000000001)return false;if(l<=r){if(now>=l && now<=r)return true;else return false;}else{if(now>=l || now<=r)return true;else return false;}}int p[400010];int t[400010][21];int A[400010];int n,m;int main(){freopen("flag.in","r",stdin);freopen("flag.out","w",stdout);splay(n),splay(m);for(int i=1;i<=n;i++){splay(e[i].l),splay(e[i].r);e[i].id=i;}sort(e+1,e+n+1,comp);for(int i=1;i<=n;i++){s[i].l=e[i].l,s[i].r=e[i].r;s[i].id=i;}sort(s+1,s+n+1,comp);for(int i=1;i<=n;i++){p[i]=p[i+n]=s[i].id;}p[n+n+1]=n+1;s[n+1].l=1000000001,s[n+1].r=1000000001;int now=p[1];for(int i=1;i<=n<<1;i++){while(in(s[p[now]].l,s[p[i]].l,s[p[i]].r)&&now!=i+n){now++;}t[i][0]=now-1;}for(int k=1;k<=20;k++){for(int i=1;i<=n<<1;i++){t[i][k]=t[t[i][k-1]][k-1];}}for(int i=1;i<=n;i++){int aim=i+n,now=i,ans=1;for(int j=20;j>=0;j--){if(t[now][j]<aim){now=t[now][j];ans+=(1<<j);}}Ans[s[i].id]=ans;}for(int i=1;i<=n;i++){//printf("%d ",Ans[i]);A[e[i].id]=Ans[i];}for(int i=1;i<=n;i++){printf("%d ",A[i]);}}
T3没调出来QAQ

0 0
原创粉丝点击