• 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;
    }

       

  • 相关阅读:
    前后端分离开发中动态菜单的两种实现方案
    Spring Security 前后端分离登录,非法请求直接返回 JSON
    Spring Boot2 系列教程(九)Spring Boot 整合 Thymeleaf
    原创的离线版 Redis 教程,给力!
    Spring Boot2 系列教程(八)Spring Boot 中配置 Https
    Anaconda创建环境、删除环境、激活环境、退出环境
    开源一个功能完整的SpringBoot项目框架
    Spring Boot和Spring Cloud学习资源推荐
    Ubuntu 18.04下安装Steam顶级在线游戏平台
    终极手撕之架构大全:分布式+开源框架+微服务+性能优化,够不够?
  • 原文地址:https://www.cnblogs.com/xiaoxubi/p/6484441.html
Copyright © 2020-2023  润新知