Codeforces_805

A.当l == r时,肯定输出这个数就可以了,当存在两个或两个以上连续的数时,2肯定是最多的数,或最多的数之一。

#include<bits/stdc++.h>
using namespace std;

int l,r;

int main()
{
    ios::sync_with_stdio(false);
    cin >> l >> r;
    if(l == r)  cout << l << endl;
    else    cout << 2 << endl;
    return 0;
}
View Code

B.aabb这个顺序一定不会有3位的回文串,并且不出现c。

#include<bits/stdc++.h>
using namespace std;

int n;

int main()
{
    ios::sync_with_stdio(false);
    cin >> n;
    int now = 0,cnt = 0;
    for(int i = 1;i <= n;i++)
    {
        if(now == 0)    cout << "a";
        else    cout << "b";
        cnt++;
        if(cnt == 2)
        {
            cnt = 0;
            now = 1-now;
        }
    }
    cout << endl;

    return 0;
}
View Code

C.1->n->2->n-1...这样的顺序。

#include<bits/stdc++.h>
using namespace std;

int n;

int main()
{
    ios::sync_with_stdio(false);
    cin >> n;
    cout << (n-1)/2 << endl;
    return 0;
}
View Code

D.我们发现,每次变换,会把a往后挪动,并且a后面的b翻倍,跑到a前面来。我们从字符串右往左找到每一个a,将其挪到所有b之后。

#include<bits/stdc++.h>
#define MOD 1000000007
using namespace std;

string s;

int main()
{
    ios::sync_with_stdio(false);
    cin >> s;
    long long ans = 0,now = 0;
    for(int i = s.length()-1;i >= 0;i--)
    {
        if(s[i] == 'b') now = (now+1)%MOD;
        else
        {
            ans = (ans+now)%MOD;
            now = (now+now)%MOD;
        }
    }
    cout << ans << endl;
    return 0;
}
View Code

E.刚开始题意看的一脸懵逼,以为T树是没有用的,但题目中有个条件,含有相同种类的点在树上是连通的,我们用这个特性dfs给G图染色即可,注意未出现的点也要染色。

#include<bits/stdc++.h>
using namespace std;

int n,m,cnt = 0,color[300005],a[300005];
vector<int> v[300005],s[300005];

void dfs(int now,int pre)
{
    map<int,int> mp;
    for(int i = 0;i < s[now].size();i++)
    {
        int t = s[now][i];
        if(color[t])    mp[color[t]] = 1;
    }
    int cntt = 0;
    for(int i = 0;i < s[now].size();i++)
    {
        int t = s[now][i];
        if(color[t])    continue;
        while(mp.count(++cntt));
        color[t] = cntt;
    }
    for(int i = 0;i < v[now].size();i++)
    {
        int t = v[now][i];
        if(t == pre)    continue;
        dfs(t,now);
    }
}

int main()
{
    ios::sync_with_stdio(false);
    cin >> n >> m;
    int ans = 1;
    for(int i = 1;i <= n;i++)
    {
        int x,y,now = 0;
        cin >> x;
        ans = max(x,ans);
        for(int j = 1;j <= x;j++)
        {
            cin >> y;
            s[i].push_back(y);
        }
    }
    for(int i = 1;i < n;i++)
    {
        int x,y;
        cin >> x >> y;
        v[x].push_back(y);
        v[y].push_back(x);
    }
    dfs(1,-1);
    cout << ans << endl;
    for(int i = 1;i <= m;i++)
    {
        if(color[i] == 0)   cout << 1 << " ";
        else    cout << color[i] << " ";
    }
    cout << endl;
    return 0;
}
View Code

F.我们求出每个连通子图中每个点的到其他点的最长距离f,每个连通子图的直径d。

对于每一个询问,若两个点在同一个连通子图,则输出-1。

否则,我们考虑两个子图的任意两个点相连后的图的直径为max(fi + fj + 1, max(d1, d2))。

将每个联通子图中所有的d排序后,枚举第一个子图每个点,二分答案为max(d1, d2)的个数,之后就好处理了。

#include<bits/stdc++.h>
using namespace std;

int n,m,q,d[100005] = {0},dd[100005],D[100005],pre[100005];
vector<int> v[100005],vv[100005];
vector<long long> s[100005];
map<int,double> mp[100005];

int findd(int x)
{
    return x == pre[x]?x:pre[x] = findd(pre[x]);
}

void join(int x,int y)
{
    int xx = findd(x),yy = findd(y);
    if(xx != yy)    pre[xx] = yy;
}

void dfs1(int now,int pre)
{
    for(int i = 0;i < v[now].size();i++)
    {
        int t = v[now][i];
        if(t == pre)    continue;
        dfs1(t,now);
        d[now] = max(d[now],d[t]+1);
    }
}
void dfs2(int now,int pre)
{
    int max1 = -1,max2 = -1;
    dd[now] = d[now];
    for(int i = 0;i < v[now].size();i++)
    {
        int t = v[now][i];
        if(d[t] > max1)
        {
            max2 = max1;
            max1 = d[t];
        }
        else    max2 = max(max2,d[t]);
    }
    for(int i = 0;i < v[now].size();i++)
    {
        int t = v[now][i];
        if(t == pre)    continue;
        int x = d[now],y = d[t];
        if(d[t] == max1)    d[now] = max2+1;
        else    d[now] = max1+1;
        d[t] = max(d[t],d[now]+1);
        dfs2(t,now);
        d[now] = x;
        d[t] = y;
    }
}
int main()
{
    ios::sync_with_stdio(false);
    cin >> n >> m >> q;
    for(int i = 1;i <= n;i++)   pre[i] = i;
    while(m--)
    {
        int x,y;
        cin >> x >> y;
        v[x].push_back(y);
        v[y].push_back(x);
        join(x,y);
    }
    for(int i = 1;i <= n;i++)
    {
        if(findd(i) == i)
        {
            dfs1(i,-1);
            dfs2(i,-1);
        }
    }
    for(int i = 1;i <= n;i++)
    {
        D[findd(i)] = max(D[findd(i)],dd[i]);
        vv[findd(i)].push_back(dd[i]);
    }
    for(int i = 1;i <= n;i++)
    {
        if(vv[i].size() == 0)   continue;
        sort(vv[i].begin(),vv[i].end());
        s[i].resize(vv[i].size());
        s[i][0] = vv[i][0];
        for(int j = 1;j < s[i].size();j++)
        {
            s[i][j] = s[i][j-1]+vv[i][j];
        }
    }
    while(q--)
    {
        int xx,yy;
        cin >> xx >> yy;
        int x = findd(xx),y = findd(yy);
        if(x == y)
        {
            cout << -1 << endl;
            continue;
        }
        if(vv[x].size() > vv[y].size() || vv[x].size() == vv[y].size() && x > y)    swap(x,y);
        if(mp[x].count(y))
        {
            cout << fixed << setprecision(9) << mp[x][y] << endl;
            continue;
        }
        double ans = 0;
        int maxx = max(D[x],D[y]);
        for(int i = 0;i < vv[x].size();i++)
        {
            int pos = upper_bound(vv[y].begin(),vv[y].end(),maxx-vv[x][i]-1)-vv[y].begin();
            ans += (long long)pos*maxx;
            ans += (long long)(vv[y].size()-pos)*(vv[x][i]+1);
            ans += (long long)s[y][s[y].size()-1];
            if(pos > 0) ans -= (long long)s[y][pos-1];
        }
        ans = ans/vv[x].size()/vv[y].size();
        mp[x][y] = ans;
        cout << fixed << setprecision(10) << ans << endl;
    }
    return 0;
}
View Code

 

posted @ 2017-05-05 23:18  zzzzzzzzhu  阅读(238)  评论(0编辑  收藏  举报