有待搞懂

A. BNU 34067 Pair

题目链接: http://www.bnuoj.com/bnuoj/problem_show.php?pid=34067

#include <iostream>
#include <cstdio>
using namespace std;

int main() 
{
    int n,t;
    scanf("%d",&t);
    while(t--)
    {
        scanf("%d",&n);
        int res = (2*n-1)/5;
        cout<<res<<endl;
    }
    return 0;
}
View Code

B. Codeforces 371D Vessels

题目链接: http://acm.hust.edu.cn/vjudge/contest/view.action?cid=38994#problem/H

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <string>
#include <vector>
#include <map>
#include <set>
#include <time.h>
#include <queue>
#include <cctype>
#include <utility>
#include <numeric>
#include <cstdlib>
#include <iomanip>
#include <sstream>
#define Mod 1000000007
#define INT 2147483647
#define pi acos(-1.0)
#define eps 1e-3
#define lll __int64
#define ll long long
using namespace std;
#define N 200010

int cap[N],jp[N],a[N];

int main()
{
    int n,m;
    int i,j;
    int op,pos,val;
    int st;
    while(scanf("%d",&n)!=EOF)
    {
        memset(cap,0,sizeof(cap));
        for(i=1;i<=n;i++)
        {
            scanf("%d",&a[i]);
            jp[i] = i;
        }
        scanf("%d",&m);
        for(i=0;i<m;i++)
        {
            scanf("%d",&op);
            if(op == 1)
            {
                scanf("%d%d",&pos,&val);
                st = jp[pos];
                while(cap[st]+val>=a[st]&&st<=n)
                {
                    val -= (a[st]-cap[st]);
                    cap[st] = a[st];
                    st++;
                }
                if(st<=n)
                    cap[st] += val;
                for(j=jp[pos];j<st;j++)
                {
                    jp[j] = st;
                }
                jp[pos] = st;
            }
            else
            {
                scanf("%d",&pos);
                printf("%d
",cap[pos]);
            }
        }
    }
    return 0;
}
View Code

C. ZOJ 1518  The Sentence is False

题目:http://acm.hust.edu.cn/vjudge/contest/view.action?cid=39061#problem/F

i&j表示第i个句子的内容是: Sentence j is true. i^j表示第i个句子的内容是: Sentence j is false.

当i&j时 i与j等价,当i^j时 i与j正好相反。利用并查集

若为: i&j 分3中情况: 1. i与j属于同一等价集合下一个循环 2.i与j的对立集合,或j与i的对立集合在同一个等价集合中.输出Inconsistent 3.合并i与j  合并 !i 与!j

若为i^j

合并i 与 !j 合并j 与 !i

最后循环每一个集合,对于每一个集合 取其 和 其对立集合的优集(对的元素多的集合)

代码:

#include <iostream>
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <utility>
#include <cstdlib>
using namespace std;
#define N 1100

int fa[N],opp[N],num[N],vis[N];

void makeset(int n)
{
    for(int i=1;i<=n;i++)
    {
        fa[i] = i;
        opp[i] = 0;
        num[i] = 1;
    }
}

int findset(int x)
{
    if(x != fa[x])
    {
        fa[x] = findset(fa[x]);
    }
    return fa[x];
}

int main()
{
    int i,j,n,flag,fai,faj,opi,opj,maxi;
    while(scanf("%d",&n)!=EOF && n)
    {
        makeset(n);
        flag = 0;
        for(i=1;i<=n;i++)
        {
            char s1[10],s2[10],s3[10];
            scanf("%s%d%s%s",s1,&j,s2,s3);
            fai = findset(i);
            faj = findset(j);
            if(opp[fai])  //如果i的根有对手,找出对手的根
                opi = findset(opp[fai]);
            else
                opi = 0;
            if(opp[faj])  //如果j的根有对手,找出对手的根
                opj = findset(opp[faj]);
            else
                opj = 0;
            if(s3[0] == 't')  //i说j是true
            {
                if(fai == faj) //如果两个在一个集合,成立
                    continue;
                if(opi == faj || fai == opj) //如果i,j相对,不符合
                {
                    flag = 1;  //出现悖论,Inconsistent
                    continue;
                }
                fa[faj] = fai; //否则合并梁集合
                num[fai] += num[faj]; //权值相加
                if(opi && opj)  //如果对手都有
                {
                    fa[opj] = opi;   //合并对手
                    num[opi] += num[opj];
                }
                else if(opi)    //如果只有i有对手  **
                    opp[faj] = opi;  //j的根的对手赋为i的对手  **
                else if(opj) //如果只有j有对手  **
                    opp[fai] = opj; //i的根的对手赋为j的对手  **
            }
            else  //i说j是错的
            {
                if(opi == faj || opj == fai) //如果本来i和j是相对的,正确,继续
                    continue;
                if(fai == faj)  //如果i和j是一个集合
                {
                    flag = 1;  //悖论
                    continue;
                }
                if(opi)  //如果i有对手,则i的对手和j是一个集合,合并
                {
                    fa[opi] = faj;
                    num[faj] += num[opi];
                }
                else  //i没有对手
                {
                    opp[fai] = faj; //i集合的对手赋为j集合
                }

                if(opj) //如果j有对手,则j的对手和i是一个集合,合并
                {
                    fa[opj] = fai;
                    num[fai] += num[opj];
                }
                else  //j没有对手,则j集合的对手赋为i集合
                {
                    opp[faj] = fai;
                }
            }
        }
        if(flag)
        {
            printf("Inconsistent
");
            continue;
        }
        maxi = 0;
        memset(vis,0,sizeof(vis));
        for(i=1;i<=n;i++)
        {
            if(i == fa[i] && !vis[i])
            {
                if(opp[i])
                {
                    opi = findset(opp[i]);
                    maxi += max(num[i],num[opi]); //取每个集合的本集合最大与其对立集合最大,求和
                    vis[opi] = 1;
                }
                else
                    maxi += num[i];
                vis[i] = 1;
            }
        }
        printf("%d
",maxi);
    }
    return 0;
}
View Code

D.POJ 1733 Parity game

题目:http://acm.hust.edu.cn/vjudge/contest/view.action?cid=39052#problem/B

代码:

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <map>
using namespace std;
#define N 10100

int fa[N],num[N];
map<int,int> mp;

void makeset(int n)
{
    for(int i=1;i<=10000;i++)
    {
        fa[i] = i;
        num[i] = 0;
    }
}

int findset(int x)
{
    if(x != fa[x])
    {
        int tmp = fa[x];
        fa[x] = findset(fa[x]);
        num[x] = num[x]^num[tmp];
    }
    return fa[x];
}

int unionset(int a,int b,char oe)
{
    int x = findset(a);
    int y = findset(b);
    int k = (oe == 'o'? 1:0);
    if(x == y)
    {
        if(num[a]^num[b] == k)
            return 1;
        else
            return 0;
    }
    else
    {
        fa[x] = y;
        num[x] = num[a]^num[b]^k;
        return 1;
    }
}

int main()
{
    int n,m,i,k,a,b,cnt;
    char ss[8];
    scanf("%d%d",&n,&m);
    makeset(n);
    k = 1;
    cnt = 0;
    for(i=1;i<=m;i++)
    {
        scanf("%d%d %s",&a,&b,ss);
        a = a-1;
        if(mp.find(a) == mp.end())
        {
            mp[a] = k++;
        }
        if(mp.find(b) == mp.end())
        {
            mp[b] = k++;
        }
        if(unionset(mp[a],mp[b],ss[0]))
            cnt++;
        else
            break;
    }
    printf("%d
",cnt);
    return 0;
}
View Code

E.HDU 1867 A+B for you again

题目:http://acm.hust.edu.cn/vjudge/contest/view.action?cid=40277#problem/K

题意:
        就是求str1 的最长后缀与 str2 的最长前缀。使得 str1+str2  的长度最小,并且字典序最小。
分析:
        利用kmp 求出最长相同的后缀和前缀。在利用串比较函数比较最小字典序。

代码:

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
using namespace std;
#define N 100007

char a[N],b[N];
int next1[N],next2[N];

void getnext(char *ss,int *next)
{
    int i = 0,j = -1;
    next[0] = -1;
    int len = strlen(ss);
    while(i<len)
    {
        if(j == -1 || ss[i] == ss[j])
            next[++i] = ++j;
        else
            j = next[j];
    }
}

int kmp(char *s1,char *s2,int *next)
{
    int i = 0,j = 0;
    int n = strlen(s1);
    int m = strlen(s2);
    while(i<n)     // 为什么不加上 j<m ?
    {
        if(j == -1 || s1[i] == s2[j])
            i++,j++;
        else
            j = next[j];
    }
    return j;
}

int main()
{
    int ka,kb;
    while(scanf("%s%s",a,b)!=EOF)
    {
        getnext(a,next1);
        getnext(b,next2);
        ka = kmp(a,b,next2);
        kb = kmp(b,a,next1);
        if(ka == kb)
        {
            if(strcmp(a,b)<=0)
                printf("%s%s
",a,b+ka);
            else
                printf("%s%s
",b,a+ka);
        }
        else if(ka>kb)
            printf("%s%s
",a,b+ka);
        else
            printf("%s%s
",b,a+kb);
    }
    return 0;
}
View Code

F.2014 Topcoder Algorithm Round 1C --950

概率期望的数学解法。

代码:

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
using namespace std;
#define N 57

class RedPaint
{
private:
public:
    double expectedCells(int N)
    {
        double res = 1.0,cur = 1.0;
        int i;
        for(i=1;i<=N;i++)
        {
            if(i%2 == 0)
                cur = cur * (i-1)/i;
            res += cur;
        }
        return res;
    }
};
View Code

G.HDU 4358 Boring counting

题解: http://www.cnblogs.com/wangfang20/archive/2013/05/24/3096620.html

四个modify

代码:

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <cmath>
#include <algorithm>
#include <string>
#include <vector>
#include <queue>
#include <stack>
#include <map>
#include <set>
#include <bitset>
#include <time.h>
#include <cctype>
#include <utility>
#include <numeric>
#include <functional>
#include <iomanip>
#include <sstream>
#define Mod 1000000007
#define SMod m
#define INint 2147483647
#define INF 0x3f3f3f3f
#define pi acos(-1.0)
#define eps 1e-8
#define lll __int64
#define ll long long
using namespace std;
#define N 100007

struct node
{
    int v,next;
}G[2*N];
struct Query
{
    int ind,l,r;
}Q[N];
int head[2*N],tot,L[N],R[N],weight[N],Time,val[N],c[N],b[N],n,ans[N];
map<int,int> mp;
vector<int> pre[N];

int lowbit(int x) { return x&-x; }
int cmp(Query ka,Query kb) { return ka.r < kb.r; }

void modify(int x,int val)
{
    while(x <= n)
    {
        c[x] += val;
        x += lowbit(x);
    }
}

int getsum(int x)
{
    int res = 0;
    while(x > 0)
    {
        res += c[x];
        x -= lowbit(x);
    }
    return res;
}

void addedge(int u,int v)
{
    G[tot].v = v;
    G[tot].next = head[u];
    head[u] = tot++;
}

void dfs(int u)
{
    L[u] = ++Time;
    val[u] = weight[u];
    for(int i=head[u];i!=-1;i=G[i].next)
    {
        int v = G[i].v;
        if(!L[v]) dfs(v);
    }
    R[u] = Time;
}

int main()
{
    int t,k,i,j,cs = 1,u,v,q;
    scanf("%d",&t);
    while(t--)
    {
        mp.clear();
        scanf("%d%d",&n,&k);
        for(i=1;i<=n;i++)
            scanf("%d",&weight[i]),b[i] = weight[i];
        sort(b+1,b+n+1);
        int ind = unique(b+1,b+n+1)-b;
        for(i=1;i<=ind;i++) mp[b[i]] = i;
        for(i=1;i<=n;i++)   weight[i] = mp[weight[i]];
        for(i=0;i<=ind;i++)
            pre[i].clear(),pre[i].push_back(0);
        memset(head,-1,sizeof(head));
        memset(c,0,sizeof(c));
        tot = Time = 0;
        memset(L,0,sizeof(L));
        memset(R,0,sizeof(R));
        for(i=1;i<n;i++)
        {
            scanf("%d%d",&u,&v);
            addedge(u,v);
            addedge(v,u);
        }
        dfs(1);
        scanf("%d",&q);
        for(i=1;i<=q;i++)
        {
            scanf("%d",&u);
            Q[i].ind = i, Q[i].l = L[u], Q[i].r = R[u];
        }
        sort(Q+1,Q+q+1,cmp);
        j = 1;
        for(i=1;i<=n;i++)
        {
            int v = val[i];
            pre[v].push_back(i);
            int now = pre[v].size()-1;
            if(now >= k)
            {
                if(now > k)
                {
                    modify(pre[v][now-k-1]+1,-1);
                    modify(pre[v][now-k]+1,1);
                }
                modify(pre[v][now-k]+1,1);
                modify(pre[v][now-k+1]+1,-1);
            }
            while(Q[j].r == i)
            {
                ans[Q[j].ind] = getsum(Q[j].l);
                j++;
            }
        }
        printf("Case #%d:
",cs++);
        for(i=1;i<=q;i++)
            printf("%d
",ans[i]);
        if(t) puts("");
    }
    return 0;
}
View Code

H. Codeforces 396C On Changing Tree

题解: http://blog.csdn.net/night_raven/article/details/20239019

代码:

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <cmath>
#include <algorithm>
#include <string>
#include <vector>
#include <queue>
#include <stack>
#include <map>
#include <set>
#include <bitset>
#include <time.h>
#include <cctype>
#include <utility>
#include <numeric>
#include <functional>
#include <iomanip>
#include <sstream>
#define Mod 1000000007
#define SMod m
#define INint 2147483647
#define INF 0x3f3f3f3f
#define pi acos(-1.0)
#define eps 1e-8
#define lll __int64
#define ll long long
using namespace std;
#define N 600017

int L[N],R[N],Time,n,m,layer,d[N];
lll c[2][N];
int head[N],tot;
struct node
{
    int v,next;
}G[N];

void addedge(int u,int v)
{
    G[tot].v = v;
    G[tot].next = head[u];
    head[u] = tot++;
}

int lowbit(int x) { return x&-x; }

void modify(int num,int x,lll val)
{
    while(x <= 2*n)
    {
        c[num][x] = (c[num][x] + val)%Mod;
        x += lowbit(x);
    }
}

lll getsum(int num,int x)
{
    lll res = 0;
    while(x > 0)
    {
        res = (res + c[num][x])%Mod;
        x -= lowbit(x);
    }
    return res;
}

void dfs(int u,int dep)
{
    L[u] = ++Time;
    d[u] = dep;
    for(int i=head[u];i!=-1;i=G[i].next)
    {
        int v = G[i].v;
        if(!L[v]) dfs(v,dep+1);
    }
    R[u] = ++Time;
}

int main()
{
    int i,j,u,v,op;
    lll x,k;
    while(scanf("%d",&n)!=EOF)
    {
        memset(c,0,sizeof(c));
        memset(L,0,sizeof(L));
        memset(R,0,sizeof(R));
        memset(head,-1,sizeof(head));
        tot = Time = 0;
        for(i=2;i<=n;i++)
        {
            scanf("%d",&u);
            addedge(u,i);
            addedge(i,u);
        }
        scanf("%d",&m);
        dfs(1,0);
        while(m--)
        {
            scanf("%d%d",&op,&u);
            if(op == 1)
            {
                scanf("%I64d%I64d",&x,&k);
                lll val = (x + d[u]*k)%Mod;
                modify(0,L[u],val);
                modify(0,R[u]+1,-val);

                modify(1,L[u],-k);
                modify(1,R[u]+1,k);
            }
            else
            {
                lll ans = ((getsum(0,L[u])+getsum(1,L[u])*d[u])%Mod+Mod)%Mod;
                printf("%I64d
",ans);
            }
        }
    }
    return 0;
}
View Code

作者:whatbeg
出处1:http://whatbeg.com/
出处2:http://www.cnblogs.com/whatbeg/
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
更多精彩文章抢先看?详见我的独立博客: whatbeg.com

原文地址:https://www.cnblogs.com/whatbeg/p/3496526.html