• 有待搞懂


    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

  • 相关阅读:
    烂泥:KVM虚拟机windows系统增加硬盘
    烂泥:KVM虚拟机克隆
    烂泥:KVM快照的创建与恢复
    烂泥:【解决】word复制windows live writer没有图片
    烂泥:ubuntu中使用virt-manager图形化新建虚拟机
    烂泥:ubuntu安装KVM虚拟机管理virt-manager
    烂泥:【解决】ubuntu使用远程NFS报错
    烂泥:kvm安装windows系统蓝屏
    烂泥:ubuntu安装vmtools
    烂泥: KVM虚拟机Linux系统增加硬盘
  • 原文地址:https://www.cnblogs.com/whatbeg/p/3496526.html
Copyright © 2020-2023  润新知