zoukankan      html  css  js  c++  java
  • 【寒假集训系列2.14】

    摆脱了110魔咒...

    30+100+0=130

    诶呀第三题没开long long一分都没有啊...

    T1Gcd

     

     

    题目描述:

    给定整数N,求1<=x,y<=N且Gcd(x,y)为素数的数对(x,y)有多少对.

    输入:

    一个整数N

    输出:

    如题

    样例输入:

    4

    样例输出:

    4

    数据规模:

        30%:N<=5000

    100%: N<=10^7

      这道题似乎以前听过啊...然而不太会诶,枚举gcd,然后找互质的数,突然一下子就忘记欧拉函数这个东西了...然后暴力于是30分

      正解:欧拉筛一下,求出欧拉函数,把所有互质的个数求出来,然后枚举gcd(),即质数,当然那些质数对(x,x)(x是质数)会被算两次,要减掉

     1 #include<cstdio>
     2 #include<cstring>
     3 #include<algorithm>
     4 #include<iostream>
     5 #include<cstdlib>
     6 #include<ctime>
     7 #include<cmath>
     8 inline int read(){
     9     int ans=0,f=1;char chr=getchar();
    10     while(!isdigit(chr)){if(chr=='-')f=-1;chr=getchar();}
    11     while(isdigit(chr)) {ans=(ans<<3)+(ans<<1)+chr-48;chr=getchar();}
    12     return ans*f;
    13 }const int N=1e7+5;
    14 int n,prime[N],p[N],cnt,phi[N];
    15 long long sum[N],ans;
    16 void pre(){
    17     phi[1]=1;
    18     for(int i=2;i<=n;++i){
    19         if(prime[i]==0) 
    20             p[++cnt]=i,phi[i]=i-1;
    21         for(int j=1;j<=cnt;++j){
    22             if(i*p[j]>n) break;
    23             prime[i*p[j]]=1;
    24             phi[i*p[j]]=(i%p[j]==0)?p[j]*phi[i]:phi[i]*(p[j]-1);//欧拉函数(积性函数)
    25         }
    26     }
    27 }
    28 int main(){
    29 //    freopen("gcd.in","r",stdin);
    30 //    freopen("gcd.out","w",stdout);
    31     n=read();pre();
    32     for(int i=1;i<=n;++i) sum[i]=sum[i-1]+phi[i];//前缀和
    33     for(int i=1;i<=cnt;++i) ans+=sum[n/p[i]]*2;
    34     printf("%lld
    ",ans-cnt);//减掉质数对个数
    35

    T2宝藏

     

    题目描述:

     

    老胡在出模拟赛时想到了这样一道题:给出一个网格图,其中某些格子有宝物,每次从左上角出发,只能向下或右走,问至少走多少次才能将宝藏捡完。但这个问题对老胡来说太简单了,现在假设每个格子中有好多宝物,而每一次经过一个格子至多只能捡走一个,至少走多少次才能把宝物全部捡完。

     

    输入:

     

    第一行为正整数T,代表数据组数。

     

    每组数据第一行为正整数N,M代表网格图有N行M列,接下来N行每行M个非负整数,表示此格子中宝物数量,0代表没有

     

    输出:

     

     输出一个整数,表示至少要走多少次。

     

    样例输入:

     

    1

     

    3 3

     

    0 1 5

     

    5 0 0

     

    1 0 0

     

    样例输出:

     

    10

     

     

     

    数据规模:

     

    30%: N,M<=5

     

    50%: N,M<=100

     

    100%: N,M<=1000,每个格子中宝物数不超过10^6 

     

    方法: Dilworth定理:DAG的最小链覆盖=最大点独立集

      然而半天过不了样例...i,j循环顺序打反了...不会的同学搜一下Dilworth定理吧(O3不开也可以)

     1 #pragma GCC optimize(3)//可以删掉,打读入优化的话完全不会TLE
     2 #include<cstdio>
     3 #include<cstring>
     4 #include<algorithm>
     5 #include<iostream>
     6 #include<cstdlib>
     7 #include<ctime>
     8 #include<cmath>
     9 using namespace std;
    10 inline int read(){
    11     int ans=0,f=1;char chr=getchar();
    12     while(!isdigit(chr)){if(chr=='-')f=-1;chr=getchar();}
    13     while(isdigit(chr)) {ans=(ans<<3)+(ans<<1)+chr-48;chr=getchar();}
    14     return ans*f;
    15     int x;scanf("%d",&x);
    16     return x;
    17 }const int M=1005;
    18 int n,m,f[M][M];
    19 int main(){
    20     freopen("treasure.in","r",stdin);
    21     freopen("treasure.out","w",stdout);
    22     int T=read();
    23     while(T--){
    24         n=read(),m=read();
    25         for(int i=1;i<=n;i++)for(int j=1;j<=m;j++)f[i][j]=read();
    26         for(int j=1;j<=m;j++)
    27             for(int i=n;i>0;i--)
    28                 f[i][j]=max(f[i][j]+f[i+1][j-1],max(f[i][j-1],f[i+1][j]));
    29         printf("%d
    ",f[1][n]);
    30     }
    31     return 0;
    32 }

    T3配对

     

    题目描述:

     

    给出一棵n个点的树,将这n个点两两配对,求所有可行的方案中配对两点间的距离的总和最大为多少。

     

    输入:

     

    一个数n(n保证为偶数)。

     

    接下来n-1行每行三个数x,y,z表示有一条长度为z的边连接x和y。

     

    输出:

     

        一个数表示答案。

     

    样例输入:

     

    6

     

    1 2 1

     

    1 3 1

     

    1 4 1

     

    3 5 1

     

    4 6 1

     

    样例输出:

     

    7

     

    样例解释:

     

    配对方案:1,2)(3,4)(5,6)

     

    数据规模:

     

    30%: N<=10

     

    50%: N<=100

     

    70%: N<=1000

     

    100%: N<=10^5,z<=10^9

     

    比赛的时候打了一个模拟退火+树剖(+线段树求距离)LCA(打算骗70分,噢真是可笑...),然后没开long long成功爆0,否则20分(应该是参数没调好)...

    正解:分开对每一条边考虑:若是要总值最大,那么一条边被计算的次数越多越好,然后记录一下每个子树的大小,取该点子树大小和除去该子树数其他部分大小的min值

    文字看不懂的话就看代码吧...出题人ciki表示这是一道智障题,然而没有一个人拿分?

     1 #include<cstdio>
     2 #include<cstring>
     3 #include<algorithm>
     4 #include<iostream>
     5 #include<cstdlib>
     6 #include<ctime>
     7 #include<cmath>
     8 #define int long long
     9 using namespace std;
    10 inline int read(){
    11     int ans=0,f=1;char chr=getchar();
    12     while(!isdigit(chr)){if(chr=='-')f=-1;chr=getchar();}
    13     while(isdigit(chr)) {ans=(ans<<3)+(ans<<1)+chr-48;chr=getchar();}
    14     return ans*f;
    15 }const int M=1e5+5;
    16 int n,x,y,z,p[M];
    17 long long ans;
    18 int head[M<<1],nxt[M<<1],ver[M<<1],val[M<<1],tot,sz[M];
    19 inline void add(int x,int y,int z){ver[++tot]=y;val[tot]=z;nxt[tot]=head[x];head[x]=tot;}
    20 const double delta=0.998,t_min=1e-14;
    21 void dfs(int x,int fa){sz[x]=1;
    22     for(int i=head[x];i;i=nxt[i]){int y=ver[i];
    23         if(y==fa) continue;
    24         dfs(y,x);sz[x]+=sz[y];
    25         ans+=val[i]*min(sz[y],n-sz[y]);
    26     }
    27 }
    28 signed main(){
    29     freopen("match.in","r",stdin);
    30     freopen("match.out","w",stdout);
    31     n=read(); 
    32     for(int i=1;i<n;i++){x=read(),y=read(),z=read();add(x,y,z),add(y,x,z);}
    33     dfs(1,0);cout<<ans;
    34     return 0;
    35 }
  • 相关阅读:
    Linux常用指令
    【OOM】记录一次生产上的OutOfMemory解决过程
    (转载)springboot + rabbitmq发送邮件(保证消息100%投递成功并被消费)
    【Idea】实用插件列表
    【工厂模式】-企业微信应用配置代码优化
    【日志追踪】(微服务应用和单体应用)-logback中的MDC机制
    行内元素进行绝对(absolute),固定(fixed)定位后会变成块级元素·
    JQuery
    单行文字居中
    后代元素 span:first-child{...}
  • 原文地址:https://www.cnblogs.com/zhenglw/p/10374296.html
Copyright © 2011-2022 走看看