zoukankan      html  css  js  c++  java
  • 2017-3-01 test

    三道好像都是HDU上的题QAQ

    题目名称都没改,差评

    T1:http://acm.hdu.edu.cn/showproblem.php?pid=5073

       被卡精度了QAQ

       先排一发序,然后发现最后未动过的点一定是一段连续的区间,且其他点都被移动至其平均数处

       所以直接O(n)乱搞即可

       P.S.HDU上好像不能用long double

    #include<iostream>
    #include<algorithm>
    #include<cstdio>
    #include<cstring>
    using namespace std;
    const int Mx=50010;
    int n,k;
    long double ans,tmp,sum,ave,a[Mx];
    bool cmp(long double a,long double b) { return a<b; }
    int main()  
    {
        int T; scanf("%d",&T);
        for(int t=1;t<=T;t++)
        {
            printf("Case #%d:
    ",t);
            tmp=0,sum=0;
            scanf("%d%d",&n,&k);
            for(int i=1;i<=n;i++) scanf("%LF",&a[i]);
            if(n==k) { cout<<"0.000000"<<endl; continue; }
            sort(a+1,a+1+n,cmp);
            for(int i=1;i<=n-k;i++) tmp+=a[i]*a[i],sum+=a[i];ave=sum/(n-k);
            ans=tmp-2*ave*sum+(n-k)*ave*ave;
            for(int l=1,r=n-k+1;r<=n;l++,r++)
            {
                tmp+=a[r]*a[r]-a[l]*a[l];
                sum+=a[r]-a[l];
                ave=sum/(n-k);
                ans=min(ans,tmp-2*ave*sum+(n-k)*ave*ave);
            }
            printf("%.8LF
    ",ans);
        }
        return 0;
    }

    T2:http://acm.hdu.edu.cn/showproblem.php?pid=5833

       一言不合就数论QAQ

       首先先预处理2000以内的素数,然后将a[]质因数分解

       我们发现,一个完全平方数的各个质因子都是偶数次方,所以每次乘起来就等价于把系数^1

       所以可以构造转移矩阵,第i行j列表示第j个素数在a[i]中的系数%2

       高斯一发然后答案即为pow(2,自由元的个数)-1,记得开long long

       P.S.自由元:消完之后一行都是0

    #include <cstdio>
    #include <cmath>
    #include <cstring>
    #include <iostream>
    #include <algorithm>
    using namespace std;
    const int Mx=2010;
    const long long p=1e9+7;
    int n,cnt,pr[Mx],vis[Mx],tran[310][310];
    void pre()
    {
        for(int i=2;i<=2000;i++)
        {
            int jud=1;
            for(int j=2;j*j<=i;j++)
                if(i%j==0) jud=0;
            if(jud) pr[++cnt]=i;
        }
    }
    long long power(long long a,long long b)
    {
        long long c=1;
        while(b)
        {
            if(b&1) c=c*a%p;
            a=a*a%p;
            b>>=1;
        }
        return c;
    }
    int gauss()
    {
        int i=1;
        for(int j=1;i<=cnt&&j<=n;i++,j++)
        {
            int tmp=i;
            for(int k=i+1;k<=cnt;k++)
                if(tran[k][j]>tran[tmp][j]) tmp=k;
            if(tmp!=i)
                for(int k=j;k<=n+1;k++) swap(tran[tmp][k],tran[i][k]);
            if(tran[i][j]==0) { i--; continue; }
            for(int k=i+1;k<=cnt;k++)
            {
                if(!tran[k][j]) continue;
                for(int l=j;l<=n+1;l++)
                    tran[k][l]=tran[k][l]^tran[i][l];
            }
        }
        return n-(i-1);
    }
    int main()
    {
        pre();
        int T; scanf("%d",&T);
        for(int t=1;t<=T;t++)
        {
            memset(tran,0,sizeof(tran));
            printf("Case #%d:
    ",t);
            scanf("%d",&n);
            for(int i=1;i<=n;i++)
            {
                long long x; scanf("%lld",&x);
                for(int j=1;j<=cnt;j++)
                {
                    int tot=0;
                    while(x%pr[j]==0)
                        x/=pr[j],tot++;
                    tran[j][i]=tot&1;
                }
            }
            printf("%lld
    ",(long long) power(2,gauss())-1);
        }
        return 0;
    }

     T3:http://acm.hdu.edu.cn/showproblem.php?pid=5770

       好麻烦啊QAQ调了半天调不出来只能把std放上去了QAQ

       orz ZSQ:http://blog.csdn.net/v5zsq/article/details/52170616

       对于一组钥匙和宝箱u,v及其lca,我们可以分类讨论,有以下四种情况

       1、u!=lca&&v!=lca:要想拿到宝箱,起点必须在u的子树中,终点必须在v的子树中

       2、u==lca:起点不能在u的子树中,终点必须在v的子树中

       3、v==lca:起点不能在v的子树中,终点必须在v的子树中

       4、u==v:起点和终点在lca的不同子树中 或 起点or终点在lca的子树中,另一个点不在lca的子树中

        这种情况为保证复杂度所以要反过来求不包含该节点的路径

        ①起点和终点都在lca的同一个儿子中

        ②起点和终点都不在在lca的子树中,即起点和终点x的dfs序都满足(x<l || x>r)

       考虑维护DFS序,将以i为根的子树处理成一个区间[l,r],则每个宝箱可以映射为一个带权矩阵,对应上述情况

       建立一个二维平面,平面上的点(x,y)表示从x走到y的价值,点权即为包含该点的所有矩阵的和

       最后用扫描线+线段树即可解决

       默默吐槽一下,std代码好吃藕啊QAQ(逃~

    #include<cstdio>
    #include<cstring>
    #include<cstdlib>
    #include<iostream>
    #include<algorithm>
    using namespace std;
    
    const int N = 200010;
    int to[N << 1], nxt[N << 1], head[N], cnt;
    void add(int x, int y){
        to[++ cnt] = y; nxt[cnt] = head[x]; head[x] = cnt;
        to[++ cnt] = x; nxt[cnt] = head[y]; head[y] = cnt;
    }
    
    struct Rec{
        int x1, x2, y1, y2, val;
    }rec[N * 10];
    struct Event{
        int l, r, y, val, rank;
    }events[N * 10];
    bool operator < (const Event &a, const Event &b){
        return a.y < b.y || (a.y == b.y && a.rank < b.rank);
    }
    
    struct treasure{
        int key, chest, val;
    }a[N];
    int st[N], ed[N], n, m, dfs_clock, dep[N], fa[N][20];
    
    int LCA(int x, int y){
        if (dep[x] < dep[y]) swap(x, y);
        int t = dep[x] - dep[y];
        for(int i = 0; i < 20; i ++) if (t >> i & 1) x = fa[x][i];
        for(int i = 19; i >= 0; i --)
            if (fa[x][i] != fa[y][i]) x = fa[x][i], y = fa[y][i];
        if (x == y) return x;
        return fa[x][0];
    }
    
    void dfs(int x){
        st[x] = ++ dfs_clock;
        for(int i = 1; (1 << i) <= dep[x]; i ++)
            fa[x][i] = fa[fa[x][i - 1]][i - 1];
        for(int i = head[x]; i; i = nxt[i])
            if (st[to[i]] == 0){
                dep[to[i]] = dep[x] + 1;
                fa[to[i]][0] = x;
                dfs(to[i]);
            }
        ed[x] = dfs_clock;
    }
    
    struct node{
        int tag, max;
    }t[N << 2];
    #define mid ((l + r) >> 1)
    #define L (o << 1)
    #define R (o << 1 | 1)
    #define lch L, l, mid
    #define rch R, mid + 1, r
    
    void Push_up(int o){
        t[o].max = max(t[L].max, t[R].max);
    }
    void change(int o, int v){
        t[o].tag += v; t[o].max += v;
    }
    void Push_down(int o){
        if (t[o].tag){
            change(L, t[o].tag);
            change(R, t[o].tag);
            t[o].tag = 0;
        }
    }
    void update(int o, int l, int r, int ql, int qr, int v){
        if (ql > qr) return;
        if (ql <= l && qr >= r) change(o, v);
        else{
            Push_down(o);
            if (ql <= mid) update(lch, ql, qr, v);
            if (qr >  mid) update(rch, ql, qr, v);
            Push_up(o);
        }
    }
    
    int main(){
        int T, cs = 0;
        scanf("%d", &T);
        while(cs < T){
            printf("Case #%d: ", ++ cs);
    
            memset(head, 0, sizeof head);
            memset(st, 0, sizeof st);
            memset(fa, 0, sizeof fa);
            memset(dep, 0, sizeof dep);
            memset(t, 0, sizeof t);
            cnt = dfs_clock = 0;
            scanf("%d%d", &n, &m);
            int x, y;
            for(int i = 1; i < n; i ++){
                scanf("%d%d", &x, &y);
                add(x, y);
            }
            dfs(1);
    //        for(int i = 1; i <= n; i ++) printf("st[%d] = %d ed[%d] = %d
    ", i, st[i], i, ed[i]);
            int tot = 0, num = 0, ans = 0, tmp = 0;
            for(int i = 1; i <= m; i ++){
                scanf("%d%d%d", &a[i].key, &a[i].chest, &a[i].val);
                int lca = LCA(a[i].key, a[i].chest);
                if (a[i].key == a[i].chest){
                    tmp += a[i].val;
                    for(int j = head[a[i].key]; j; j = nxt[j])
                        if (to[j] != fa[a[i].key][0]){
                            rec[++ tot] = (Rec){st[to[j]], ed[to[j]], st[to[j]], ed[to[j]], -a[i].val};
                        }
                    if (1 <= st[a[i].key] - 1 && ed[a[i].key] + 1 <= n){
                        rec[++ tot] = (Rec){1, st[a[i].key] - 1, ed[a[i].key] + 1, n, -a[i].val};
                        rec[++ tot] = (Rec){ed[a[i].key] + 1, n, 1, st[a[i].key] - 1, -a[i].val};
                    }
                    if (1 <= st[a[i].key] - 1)
                        rec[++ tot] = (Rec){1, st[a[i].key] - 1, 1, st[a[i].key] - 1, -a[i].val};
                    if (ed[a[i].key] + 1 <= n)
                        rec[++ tot] = (Rec){ed[a[i].key] + 1, n, ed[a[i].key] + 1, n, -a[i].val};
                }else if (a[i].key == lca){
                    for(int j = head[a[i].key]; j; j = nxt[j])
                        if (to[j] != fa[a[i].key][0] && LCA(to[j], a[i].chest) == to[j]){
                            y = to[j];
                            break;
                        }
                    if (1 <= st[y] - 1) rec[++ tot] = (Rec){1, st[y] - 1, st[a[i].chest], ed[a[i].chest], a[i].val};
                    if (ed[y] + 1 <= n) rec[++ tot] = (Rec){ed[y] + 1, n, st[a[i].chest], ed[a[i].chest], a[i].val};
                }else if (a[i].chest == lca){
                    for(int j = head[a[i].chest]; j; j = nxt[j])
                        if (to[j] != fa[a[i].chest][0] && LCA(to[j], a[i].key) == to[j]){
                            y = to[j];
                            break;
                        }
                    if (1 <= st[y] - 1) rec[++ tot] = (Rec){st[a[i].key], ed[a[i].key], 1, st[y] - 1, a[i].val};
                    if (ed[y] + 1 <= n) rec[++ tot] = (Rec){st[a[i].key], ed[a[i].key], ed[y] + 1, n, a[i].val};
                }else{
                    rec[++ tot] = (Rec){st[a[i].key], ed[a[i].key], st[a[i].chest], ed[a[i].chest], a[i].val};
                }
    //            if (rec[tot].x1 == 0) printf("%d %d %d lca = %d
    ", a[i].key, a[i].chest, a[i].val, lca);
            }
    //        for(int i = 1; i <= tot; i ++)
    //            printf("%d %d %d %d %d
    ", rec[i].x1, rec[i].x2, rec[i].y1, rec[i].y2, rec[i].val);
            int tt = 0;
            for(int i = 1; i <= tot; i ++){
    //            if (rec[i].x1 == 0 && rec[i].x2 == 0) printf("%d
    ", ++ tt);
                events[++ num] = (Event){rec[i].x1, rec[i].x2, rec[i].y1, rec[i].val, 1};
                events[++ num] = (Event){rec[i].x1, rec[i].x2, rec[i].y2 + 1, -rec[i].val, 0};
            }
            sort(events + 1, events + num + 1);
            for(int i = 1; i <= num; i ++){
                if (events[i].y > events[i - 1].y || i == 1) ans = max(ans, t[1].max);
                update(1, 1, n, events[i].l, events[i].r, events[i].val);
                if (i == num) ans = max(ans, t[1].max);
    //            printf("%d
    ", t[1].max);
            }
            printf("%d
    ", ans + tmp);
        }
        return 0;
    }

       

  • 相关阅读:
    AUDIT审计的一些使用
    HOW TO PERFORM BLOCK MEDIA RECOVERY (BMR) WHEN BACKUPS ARE NOT TAKEN BY RMAN. (Doc ID 342972.1)
    使用BBED理解和修改Oracle数据块
    Using Class of Secure Transport (COST) to Restrict Instance Registration in Oracle RAC [ID 1340831.1]
    调试利器GDB概念
    第4章 思科IOS
    第3章 ip地址和子网划分
    第2章 TCPIP
    2020年阅读过的黑客资源推荐篇
    第1章 计算机网络
  • 原文地址:https://www.cnblogs.com/xiaoxubi/p/6484441.html
Copyright © 2011-2022 走看看