codeforces AIM Tech Round (Div. 2)

A题:水。

/*
ID: huanrui ke
PROG: AIM Tech Round (Div. 2)
LANG: C++
*/
#include<bits/stdc++.h>
#define REP(i,a,b) for(int i=a;i<=b;i++)
#define MS0(a) memset(a,0,sizeof(a))

using namespace std;

typedef long long ll;
const int maxn=1000100;
const int INF=1e9+10;

double d,L,v1,v2;

int main()
{
    //freopen("in.txt","r",stdin);
    while(cin>>d>>L>>v1>>v2){
        printf("%.7f\n",(L-d)/(v1+v2));
    }
    return 0;
}
View Code

B题:水。

/*
ID: huanrui ke
PROG: AIM Tech Round (Div. 2)
LANG: C++
*/
#include<bits/stdc++.h>
#define REP(i,a,b) for(int i=a;i<=b;i++)
#define MS0(a) memset(a,0,sizeof(a))

using namespace std;

typedef long long ll;
const int maxn=1000100;
const int INF=1e9+10;

int n,a[maxn];
map<ll,int> mp;

int main()
{
    //freopen("in.txt","r",stdin);
    while(cin>>n){
        REP(i,1,n) scanf("%d",&a[i]);
        mp.clear();
        sort(a+1,a+n+1);
        ll ans=0;
        for(int i=n;i>=1;i--){
            if(mp[a[i]]){
                while(a[i]>0&&mp[a[i]]) a[i]--;
            }
            ans+=a[i];
            mp[a[i]]=1;
        }
        cout<<ans<<endl;
    }
    return 0;
}
View Code

C题:直接判补图会简单一点,对补图用a-c染色,对于单独的点直接染为b,最后验证一下就可以了。

/*
ID: huanrui ke
PROG: AIM Tech Round (Div. 2)
LANG: C++
*/
#include<bits/stdc++.h>
#define REP(i,a,b) for(int i=a;i<=b;i++)
#define MS0(a) memset(a,0,sizeof(a))

using namespace std;

typedef long long ll;
const int maxn=510;
const int INF=1e9+10;

int g[maxn][maxn];
int e[maxn][maxn];
int n,m;
int u,v;
int deg[maxn];
char vis[maxn];

void dfs(int u,char c)
{
    vis[u]=c;
    for(int v=1;v<=n;v++){
        if(vis[v]!='#') continue;
        if(!e[u][v]){
            if(c=='a') dfs(v,'c');
            else if(c=='c') dfs(v,'a');
        }
    }
}

bool jud()
{
    REP(i,1,n) REP(j,1,n) g[i][j]=1;
    REP(i,1,n){
        REP(j,1,n){
            if(i==j) continue;
            if(vis[i]=='a'&&vis[j]=='c') g[i][j]=0;
            if(vis[i]=='c'&&vis[j]=='a') g[i][j]=0;
        }
    }
    /*
    REP(i,1,n){
        REP(j,1,n){
            cout<<g[i][j]<<" ";
        }
        cout<<endl;
    }
    REP(i,1,n){
        REP(j,1,n){
            cout<<e[i][j]<<" ";
        }
        cout<<endl;
    }
    */
    REP(i,1,n){
        REP(j,1,n){
            if(i==j) continue;
            if(e[i][j]!=g[i][j]) return 0;
        }
    }
    return 1;
}

int main()
{
    //freopen("in.txt","r",stdin);
    while(cin>>n>>m){
        MS0(e);MS0(deg);MS0(g);
        REP(i,1,m){
            scanf("%d%d",&u,&v);
            e[u][v]=e[v][u]=1;
        }
        REP(i,1,n){
            REP(j,1,n){
                if(i==j) continue;
                if(!e[i][j]){
                    deg[i]++;
                }
            }
        }
        //REP(i,1,n) deg[i]/=2;
        //REP(i,1,n) cout<<deg[i]<<" ";cout<<endl;
        memset(vis,'#',sizeof(vis));
        REP(i,1,n){
            if(vis[i]!='#') continue;
            if(deg[i]>0){
                dfs(i,'a');
            }
        }
        REP(i,1,n) if(vis[i]=='#') vis[i]='b';
        //REP(i,1,n) cout<<vis[i];cout<<endl;
        if(jud()){
            puts("Yes");
            REP(i,1,n) printf("%c",vis[i]);
            puts("");
        }
        else puts("No");
    }
    return 0;
}
View Code

D题:

枚举出a[1],a[1]+1,a[1]-1,a[n],a[n]+1,a[n]-1的所有质因子,分别判断,然后预处理保留前缀f[i]和保留后缀g[j],代价就是f[i]+(j-i-1)*b+g[j]=(f[i]-(i+1)*b) + (g[j]+j*b) ,然后枚举i快速找到j就可以了。

复杂度o(n*质因子个数)=o(n*log(1e9)) .

#include<bits/stdc++.h>
#define REP(i,a,b) for(int i=a;i<=b;i++)
#define MS0(a) memset(a,0,sizeof(a))

using namespace std;

typedef long long ll;
const int maxn=1000100;
const int INF=1e9+10;
const ll MAX=1e18+10;

int n;ll a,b;
ll x[maxn];
ll f[maxn],g[maxn];
vector<ll> prime;
bool isprime[maxn];
set<ll> s;

void getPrime()
{
    memset(isprime,1,sizeof(isprime));
    isprime[1]=0;
    REP(i,2,maxn-1){
        if(!isprime[i]) continue;
        for(int j=i+i;j<maxn;j+=i) isprime[j]=0;
    }
    REP(i,2,maxn-1) if(isprime[i]) prime.push_back(i);
    //for(int i=0;i<10;i++) cout<<prime[i]<<" ";cout<<endl;
}

ll change(ll x,ll p)
{
    if(x%p==0) return 0;
    if((x-1)%p==0||(x+1)%p==0) return b;
    return -1;
}

ll solve(ll p)
{
    int L=n+1,R=0;
    f[0]=0;
    int tag=0;
    REP(i,1,n){
        ll t=change(x[i],p);
        if(t==-1){
            L=i;tag=1;
        }
        if(tag) f[i]=MAX;
        else f[i]=f[i-1]+t;
    }
    g[n+1]=0;
    tag=0;
    for(int i=n;i>=1;i--){
        ll t=change(x[i],p);
        if(t==-1){
            R=i;tag=1;
        }
        if(tag) g[i]=MAX;
        else g[i]=g[i+1]+t;
    }
    /// f[i] + (j-i-1)*b + g[j]
    ///= f[i] + g[j]+j*b - (i+1)*b
    ///= ( f[i]-(i+1)*b ) + min( g[j]+j*b [j=i+1~n] )
    ll G=g[n+1]+(n+1)*a;
    ll res=f[n];
    for(int i=n;i>=0;i--){

        res=min(res,f[i]-(i+1)*a+G);
        G=min(G,g[i]+i*a);
    }
    return res;
}

void get(ll x)
{
    if(x==0||x==1) return;
    for(int i=0;i<prime.size();i++){
        ll t=prime[i];
        if(t*t>x) break;
        if(x%t==0){
            s.insert(t);
            while(x%t==0) x/=t;
        }
    }
    if(x>1) s.insert(x);
}

void Init()
{
    s.clear();
    get(x[1]);get(x[1]+1);get(x[1]-1);
    get(x[n]);get(x[n]+1);get(x[n]-1);
    //for(set<ll>::iterator it=s.begin();it!=s.end();++it) cout<<(*it)<<" ";cout<<endl;
}

int main()
{
    freopen("in.txt","r",stdin);
    getPrime();
    while(cin>>n>>a>>b){
        REP(i,1,n) scanf("%I64d",&x[i]);
        Init();
        ll ans=MAX;
        for(set<ll>::iterator it=s.begin();it!=s.end();++it){
            ans=min(ans,solve(*it));
        }
        cout<<ans<<endl;
    }
    return 0;
}
View Code

 

posted @ 2016-02-06 00:00  __560  阅读(238)  评论(0编辑  收藏  举报