codeforces ABBYY Cup 2.0

 B

RMQ+LCA+边双连通

View Code
#include<string.h>
#include<stdio.h>
#include<vector>
#include<math.h>
using namespace std;
const int M =100100;
const double inf = 1e20;
inline int min(int a,int b){return a<b?a:b;}
int tdfn,tot;
int dp[20][2*M],vis[M];
int B[2*M],LOG[2*M],used[M],F[2*M],pos[M];
int Btype,Time,dfn[M],low[M],Belong[M],st[M],Top;
vector<int> newe[2*M];
vector<pair<int,int> >rec;
void rmq_init(int n,int num[])
{
    int i,j;
    for(j=1;j<=n;j++) 
        dp[0][j]=num[j];
    for(j=1;j<=LOG[n];j++)
    {
        int limit=n+1-(1<<j);
        for(i=1;i<=limit;i++)
        {
            int x=i+(1<<j>>1);
            dp[j][i]=min(dp[j-1][x],dp[j-1][i]);
        }
    }
}
int rmq(int l,int r,int num[])
{
    int m=LOG[r-l+1];
    return min(dp[m][l],dp[m][r-(1<<m)+1]);
}
int sum[M];
void lca_dfs(int s)
{
    int i,t;
    used[s]=1;
    int tmp=++tdfn;
    B[++tot]=tmp;F[tmp]=s;
    pos[s]=tot;
    for(i=0;i<newe[s].size();i++)
    {
        t=newe[s][i];
        if(used[t])  continue;
        sum[t]=sum[s]+1;
        lca_dfs(t);
        B[++tot]=tmp;//backtrack
    }
}
int lca(int a,int b)
{
    if(pos[a]>pos[b]) swap(a,b);
    int ans=rmq(pos[a],pos[b],B);
    return F[ans];
}
struct Edge
{
    int s,t;
    int next;
    int vis;
}edge[1000005];
int head[M];
int E;
void add_edge(int s,int t)
{
    edge[E].s=s;
    edge[E].t=t;
    edge[E].vis=0;
    edge[E].next=head[s];
    head[s]=E++;
}
void dfs(int s)
{
    int i,t,id;
    st[++Top]=s;
    dfn[s]=low[s]=++Time;
    for (i=head[s];i!=-1;i=edge[i].next)
    {    
        if(edge[i].vis)continue;    
        edge[i].vis=edge[i^1].vis=1;
        t=edge[i].t;
        if (!dfn[t])
        {
            dfs(t);
            low[s]=min(low[s],low[t]);
        }
        else low[s]=min(low[s],dfn[t]);
        if(low[t]>dfn[s])  
        {
            //    printf("s=%d t=%d\n",s,t);
            rec.push_back(make_pair(s,t));
        }
    }
    if(dfn[s]==low[s])
    {
        Btype++;
        do{
            t=st[Top--];
            Belong[t]=Btype;
        }while(t!=s);
    }
}
void SCC(int n)
{
    int i;
    Time=0;Btype=0;Top=0;
    memset(dfn,0,sizeof(int)*(n+1));
    for(i=1;i<=n;i++)if(!dfn[i])
        dfs(i);
}
int main()
{
    int i,n,m,a,b,w,k;
    LOG[0]=-1;
    for(i=1;i<2*M;i++)  LOG[i]=LOG[i>>1]+1;
    while(scanf("%d%d",&n,&m)!=EOF)
    {
        E=0;
        memset(head,-1,sizeof(head));
        for(i=0;i<m;i++)
        {
            scanf("%d%d",&a,&b);
            add_edge(a,b);
            add_edge(b,a);
        }
        SCC(n);
        for(i=0;i<=Btype;i++) newe[i].clear();
        for(i=0;i<rec.size();i++)
        {
            newe[Belong[rec[i].first]].push_back(Belong[rec[i].second]);
            newe[Belong[rec[i].second]].push_back(Belong[rec[i].first]);
        }
        sum[1]=0;tdfn=0;tot=0;memset(used,0,sizeof(used));
        lca_dfs(1);
        rmq_init(tot,B);
        scanf("%d",&k);
        while(k--)
        {
            scanf("%d%d",&a,&b);
            int aa=Belong[a],bb=Belong[b];
            printf("%d\n",sum[aa]+sum[bb]-2*sum[lca(aa,bb)]);
        }
    }
    return 0;
}

 

C题:

codeforces题目链接http://codeforces.com/contest/178/problem/C3

各种stl,各种没用过。。。

于是果断学习了,自己写了一下,调试什么的也还算顺利

View Code
#pragma warning (disable:4786)
#include <cstdio>
#include <cstring>
#include <vector>
#include <algorithm>
#include <map>
#include <set>
using namespace std;
const int maxn = 200010;
int h,m,n;
int vis[maxn],seq[maxn],rank[maxn];
set<int> a[maxn];
map<int,pair<int,int> > history;
void release(pair<int,int> p){
    a[p.first].insert(p.second);
}
int main()
{
    int i,r=0,id,hash;
    __int64 ans=0;
    scanf("%d%d%d",&h,&m,&n);
    for(i=0;i<h;i++)
    if(!vis[i])
    {
        for(int c=0,j=i;!vis[j];j=(j+m)%h,c++)
        {
           rank[j]=r;
           seq[j]=c;
           a[r].insert(c);
           vis[j]=1;
        }
        r++;
    }char s[5];
    while(n--)
    {
        scanf("%s%d",s,&id);
        if(s[0]=='-')    release(history[id]);
        else 
        {
            scanf("%d",&hash);
            int A=rank[hash],B=seq[hash];
            set<int> ::iterator it=a[A].lower_bound(B);
            if(it==a[A].end())
            {
                it=a[A].begin();
                ans+=h/r-B+*it;
            }
            else    ans+=*it-B;
            history[id]=make_pair(A,*it);//要先映射再删除,不然it就为空了
            a[A].erase(it);
        }
    }
    printf("%I64d\n",ans);
    return 0;
}

 

f1

两种暴力方法

dfs    

View Code
#include<cstdio>
#include<cstring>
char str[30][510];
int len[50];
int dis[30][30],path[30];
int ans=0,k,n;
void dfs(int a,int b,int res)
{
    if(b==k) 
    {
        if(res>ans) ans=res;
        return ;
    }
    if(a==n) return ;
    for(int i=a;i<n;i++)
    {
        int s=res;
        for(int j=0;j<b;j++) s+=dis[path[j]][i];
        path[b]=i;
        dfs(i+1,b+1,s);
    }
}
int main()
{
    int i,j,m,s;
    while(scanf("%d%d",&n,&k)!=EOF)
    {
        for(i=0;i<n;i++) 
        {
            scanf("%s",str[i]);
            len[i]=strlen(str[i]);
        }
        for(i=0;i<n;i++)
        {
            for(j=i+1;j<n;j++)
            {
                for(s=0;s<len[i]&&s<len[j];s++)
                    if(str[i][s]!=str[j][s]) break;
                dis[i][j]=dis[j][i]=s;
            }
        }
        dfs(0,0,0);
        printf("%d\n",ans);
    }
    return 0;
}

状态压缩

View Code
#include<cstdio>
#include<cstring>
char str[30][510];
int len[50];
int dis[30][30];
int main()
{
    int n,k,i,j,m,s;
    while(scanf("%d%d",&n,&k)!=EOF)
    {
        for(i=0;i<n;i++) 
        {
            scanf("%s",str[i]);
            len[i]=strlen(str[i]);
        }
        for(i=0;i<n;i++)
        {
            for(j=i+1;j<n;j++)
            {
                for(s=0;s<len[i]&&s<len[j];s++)
                    if(str[i][s]!=str[j][s]) break;
                dis[i][j]=dis[j][i]=s;
            }
        }
        int ans=0;
        for(i=0;i<(1<<n);i++)
        {
            for(j=0,m=0;j<n;m+=(i>>j)&1,j++);
            if(m!=k) continue;
            for(m=0,j=0;j<n;j++)
                 if((i>>j)&1)
                     for(int x=j+1;x<n;x++)
                         if((i>>x)&1) 
                             m+=dis[j][x];
           if(m>ans) ans=m;
        }
        printf("%d\n",ans);
    }
    return 0;
}

 

 

 

posted @ 2012-04-29 16:34  Because Of You  Views(420)  Comments(0Edit  收藏  举报