ARC 074

来源:互联网 发布:安卓淘宝引流量软件 编辑:程序博客网 时间:2024/06/06 15:47

感觉这场ARC的题目挺适合中国选手…所以好像很多人AK..

D
用堆预处理出1~i,i~3N保留N个数的最小和最大和
枚举剩下的2N个数的第N个数

E
f[r][g][b]表示r,g,b为三种颜色最后出现的位置,i=max(r,g,b),1~i以内的限制都满足,1~i的填色数

code:

#include<set>#include<map>#include<deque>#include<queue>#include<stack>#include<cmath>#include<ctime>#include<bitset>#include<string>#include<vector>#include<cstdio>#include<cstdlib>#include<cstring>#include<climits>#include<complex>#include<iostream>#include<algorithm>#define ll long long#define __ %=Modusing namespace std;const ll Mod = 1e9+7;const int maxn = 305;int n,m;struct node{int l,r,x;}a[maxn];inline bool cmp(const node x,const node y){return x.r<y.r;}ll f[maxn][maxn][maxn];void trans(const int i,const int x,const int y,const int z){    ll &tmp=f[x][y][z];    (f[i][y][z]+=tmp)__;    (f[x][i][z]+=tmp)__;    (f[x][y][i]+=tmp)__;    tmp=0;}int cal(const int x,const int y,const int z,const int l){    int re=0;    if(x>=l) re++;    if(y>=l) re++;    if(z>=l) re++;    return re;}void judge(const int x,const int y,const int z,int l,int r){    bool flag=true;    for(int i=l;i<=r;i++)    {        if(a[i].x!=cal(x,y,z,a[i].l)){ flag=false; break; }    }    if(!flag) f[x][y][z]=0;}int main(){    scanf("%d%d",&n,&m);    for(int i=1;i<=m;i++) scanf("%d%d%d",&a[i].l,&a[i].r,&a[i].x);    sort(a+1,a+m+1,cmp);    f[0][0][0]=1ll; int pos=1;    for(int i=1;i<=n;i++)    {        for(int j=i-1;j>=0;j--) for(int k=i-1;k>=0;k--)        {            if(f[i-1][j][k]) trans(i,i-1,j,k);            if(f[j][i-1][k]) trans(i,j,i-1,k);            if(f[j][k][i-1]) trans(i,j,k,i-1);        }        int np=pos; while(np<=m&&a[np].r==i) np++; np--;        if(pos>np) continue;        for(int j=i-1;j>=0;j--) for(int k=i-1;k>=0;k--)        {            if(f[i][j][k]) judge(i,j,k,pos,np);            if(f[j][i][k]) judge(j,i,k,pos,np);            if(f[j][k][i]) judge(j,k,i,pos,np);        }        pos=np+1;    }    ll re=0;    for(int j=n-1;j>=0;j--) for(int k=n-1;k>=0;k--)    {        if(f[n][j][k]) (re+=f[n][j][k])__;        if(f[j][n][k]) (re+=f[j][n][k])__;        if(f[j][k][n]) (re+=f[j][k][n])__;    }    printf("%lld\n",re);    return 0;}

F
对于(i,j)的荷叶,i和j之间连流量为1的双向边,st和sx,sy连流量无限的双向边,ed同理,跑最小割

code:

#include<set>#include<map>#include<deque>#include<queue>#include<stack>#include<cmath>#include<ctime>#include<bitset>#include<string>#include<vector>#include<cstdio>#include<cstdlib>#include<cstring>#include<climits>#include<complex>#include<iostream>#include<algorithm>#define ll long long#define inf 1e9using namespace std;const int maxn = 110;const int maxp = 1100;const int maxm = 110000;int n,m;struct edge{int y,c,nex;}a[maxm]; int len,fir[maxp],fi[maxp];inline void ins(const int x,const int y,const int c){a[++len]=(edge){y,c,fir[x]};fir[x]=len;}int st,ed;int h[maxp];queue<int>q;bool bfs(){    for(int i=1;i<=ed;i++) h[i]=0;    h[st]=1; q.push(st);    while(!q.empty())    {        const int x=q.front(); q.pop();        for(int k=fir[x],y=a[k].y;k;k=a[k].nex,y=a[k].y)            if(!h[y]&&a[k].c) h[y]=h[x]+1,q.push(y);    }    return h[ed]>0;}int dfs(const int x,const int flow){    if(x==ed) return flow;    int delta=0;    for(int &k=fi[x],y=a[k].y;k&&delta<flow;k=a[k].nex,y=a[k].y) if(h[y]==h[x]+1&&a[k].c)    {        int mk=dfs(y,min(a[k].c,flow-delta));        delta+=mk;        a[k].c-=mk; a[k^1].c+=mk;    }    if(!delta) h[x]=0;    return delta;}int Flow(){    int re=0;    while(bfs())     {        for(int i=1;i<=ed;i++) fi[i]=fir[i];        re+=dfs(st,inf);    }    return re;}int rec[maxn][maxn],sx,sy,ex,ey;char str[maxn];int main(){    scanf("%d%d",&n,&m);    for(int i=1;i<=n;i++)    {        scanf("%s",str);        for(int j=0;j<m;j++)        {            if(str[j]=='o') rec[i][j+1]=1;            else if(str[j]=='S') sx=i,sy=j+1;            else if(str[j]=='T') ex=i,ey=j+1;        }    }    if(sx==ex||sy==ey) return puts("-1"),0;    len=1;    for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) if(rec[i][j])    {        ins(i,n+j,1); ins(n+j,i,1);    }    st=n+m+1,ed=st+1;    ins(st,sx,inf); ins(st,n+sy,inf);    ins(ex,ed,inf); ins(n+ey,ed,inf);    printf("%d\n",Flow());    return 0;}
原创粉丝点击