zoukankan      html  css  js  c++  java
  • 2017NOIp模拟赛08.20

    今天没听见学长说用cena不要建子文件夹,手贱建了啊啊啊然后就gg了啊,哭qwq

    Ant

    问题描述

      询问 1~n 中间约数个数最多的数

    输入格式

      一个数 n

    输出格式

      输出 1~n 中间约数个数最多的数,如果有多个输出最小的那个

    样例输入

      1000

    样例输出

      840

    数据规模和约定

      10%的数据满足:1≤n≤5000。

      30%的数据满足:1≤n≤100000。

      100%的数据满足:1≤n≤2000000000。

    题解:

      做过的原题(不太记得是哪个oj了,说不定是openjudge),好像以前第一次写的时候是直接抄的题解啊……

      很简单,首先你要会求一个数的约数个数,其结果为:所有质因数的指数加上1后的乘积。

      看到题中还有一个小小的坑:如有多组解输出最小的那个。

      这就要求我们分解质因数后,限制较小质因数的指数,必须严格大于比它大的质因数的指数。(感觉说起来好绕口啊)比如,2^3*3^1=24,2^2*3^2=36,24<36。

      证明:反证法,如果你有一个已经分解了的数,其中2的指数比3小,那你显然可以找到一个2的指数再加1,3的指数再减1的乘积。这个乘积必定比之前的小,而且计算约数的个数也和之前一样。(顺便%一下机房大佬lyy)

      最后限制一下输出。

     1 #include<iostream>
     2 #include<cmath>
     3 #include<algorithm>
     4 #include<cstring>
     5 #include<cstdio>
     6 #define ll long long
     7 using namespace std;
     8 inline void Edwina()
     9 {
    10     freopen("ant.in","r",stdin);
    11     freopen("ant.out","w",stdout);
    12 }
    13 int prime_num[20]={0,2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,51};
    14 ll mmax,n,ans;
    15 void solve(ll now,int prim,int tot,int up)//now是当前值,tot为约数的个数,up限制指数大小 
    16 {
    17     if(((tot==mmax)&& (now<ans))||(tot>mmax))
    18         ans=now,mmax=tot;
    19     //mmax=max(tot,mmax),ans=min(now,ans);
    20     int nxt_up=0,l=1,sum_prim;
    21     ll i=now;
    22     while(nxt_up<up)
    23     {
    24         nxt_up++;l++;
    25         if(n/i<prime_num[prim])
    26             break;
    27         sum_prim=tot*l;
    28         i*=prime_num[prim];
    29         if(i<=n)
    30             solve(i,prim+1,sum_prim,nxt_up);
    31     }
    32 }
    33 int main()
    34 {
    35     Edwina();
    36     mmax=-1;ans=-1;
    37     scanf("%lld",&n);
    38     solve(1,1,1,30);
    39     printf("%lld",ans);
    40     fclose(stdin);
    41     fclose(stdout);
    42     return 0;
    43 }
    View Code

    Red

    问题描述

      桌面上有 R 张红牌和 B 张黑牌,随机打乱顺序后放在桌面上,开始一张一张地翻牌,翻到红牌得到 1 美元,黑牌则付出 1 美元。可以随时停止翻牌,在最优策略下平均能得到多少钱。

    输入格式

      一行输入两个数 R、B。

    输出格式

      在最优策略下平均能得到多少钱。

    样例输入

      5 1

    样例输出

      4.166666

    数据规模和约定

      R,B<=5000

      输出答案时,小数点后第六位后的全部去掉,不要四舍五入。

    题解:

      一看就是期望dp。我们定义f(i,j)为当前状态下,还有i张红牌和j张黑牌没翻的期望受益,转移时两种情况下的结果都要考虑。

      于是f[i][j]=max(0,i/(i+j)*(f[i-1][j]+1)+j/(i+j)*(f[i][j-1]-1))

      空间注意要用滚动数组。

     1 #include<iostream>
     2 #include<cmath>
     3 #include<algorithm>
     4 #include<cstring>
     5 #include<cstdio>
     6 #define ans1 ((f[j-1][end]+1)*j/i)
     7 #define ans2 ((f[j][end]-1)*(i-j)/i)
     8 #define ll long long
     9 using namespace std;
    10 //const int maxn=5001;
    11 inline void Edwina()
    12 {
    13     freopen("red.in","r",stdin);
    14     freopen("red.out","w",stdout);
    15 }
    16 double f[10009][2];//开滚动数组 
    17 double mmax(double a,double b){return a>b?a:b;}
    18 int main()
    19 {
    20     Edwina();
    21     int R,B,k=0,end=1;
    22     scanf("%d%d",&R,&B);
    23     for(int i=1;i<=R+B;i++,end^=1,k^=1)
    24     {
    25         for(int j=0;j<=i&&j<=R;j++)
    26         {
    27             if(j==0)
    28                 f[j][k]=0;
    29             else
    30             {
    31                 if(i==j)
    32                     f[j][k]=j;
    33                 else
    34                     f[j][k]=mmax(0,ans1+ans2);
    35                     //ans1 ((f[j-1][end]+1)*j/i)
    36                     //ans2 ((f[j][end]-1)*(i-j)/i)
    37             }
    38         }
    39     }
    40     printf("%.6lf
    ",floor(f[R][end]*1000000)/1000000);//对于小数位的处理 
    41     //ll ans=(ll)(f[R][end]*1000000);
    42     //printf("%lld.%06lld
    ",ans/1000000,ans%1000000);
    43     fclose(stdin);
    44     fclose(stdout);
    45     return 0;
    46 }
    View Code

    Alone
    问题描述
      QY 以前曾经同时与一些妹子交往,妹子们之间的关系成一棵树。一开始每个妹子对他都有一个好感度。因为 QY 太神犇了,所以很多人给他出了一些题目,
    他每 AC 一道 A 出给他的题目会导致以 A 为根的子树中除了 A 以外所有的妹子对他的好感度下降。

      操作 1:QY AC 了 A 出的题目导致以 A 为根的子树中除了 A 以外所有的妹子对他的好感度下降。

      操作 2: QY 想要知道以 A 为根的子树中除了 A 以外还有几个对他好感度>0 的。

      树根处的妹子编号为 0,她对 QY 的好感度可以看做是无限的。

    输入格式
      第一行一个整数 N。
      代表有 N+1 个妹子,编号分别是 0~N。
      接下来 N 行每行两个整数,第一个整数表示编号为 i 的妹子的好感度 H,第二个整数表示第i个妹子在树上的父亲Fi(保证妹子i的父亲的编号小于i)
      接下来一行一个整数 Q。
      接下来 Q 行,每行一个操作。
      第一类操作读入三个参数{1,Ai,Xi}表示 QY使以 Ai 为根的子树中除了 Ai 以外所有的妹子对他的好感度下降 Xi。
      第二类操作读入两个参数{2,Ai}表示询问以 Ai 为根的子树中除了 Ai 以外有几个妹子对 QY的好感度>0。
    输出格式
      对于每一个第二类操作,输出一行一个整数,表示所询问的答案。
    样例输入
    4
    1 0
    2 0
    2 2
    1 2
    4
    1 2 1
    2 2
    1 0 1
    2 0
    样例输出
    1
    1
    数据规模和约定
      对于 30%的数据,满足 1<=N<=1000,1<=Q<=1000。
      对于另外 20%的数据,保证数据纯随机生成。
      对于 100%的数据,满足 1<=N<=10^5,1<=Q<=10^5,0<=Ai<=N,1<=Hi<=10^9,1<=Xi<=10^4,0<=Fi<i。

      emmm……先贴上fy学长的std……

      1 #include<cstdio>
      2 #include<cstdlib>
      3 #include<cstring>
      4 #include<iostream>
      5 #include<algorithm>
      6 #define N 100010
      7 using namespace std;
      8 struct treenode
      9 {
     10     int l,r,lazy,minn,sum,mid;
     11 }tree[N*4];
     12 int tot=-1,ver[N],next[N],head[N],first[N],second[N],v[N],tim=0,a,h[N],b,c,n,m,used[2];
     13 void add(int a,int b)
     14 {
     15     tot++;
     16     ver[tot]=b;
     17     next[tot]=head[a];
     18     head[a]=tot;
     19 }
     20 
     21 void build(int tr,int l,int r)
     22 {
     23     tree[tr].l=l;
     24     tree[tr].r=r;
     25     tree[tr].lazy=0;
     26     if (l==r)
     27     {
     28         tree[tr].sum=1;
     29         tree[tr].minn=h[v[l]];
     30         return;
     31     }
     32     int mid=(l+r)/2;
     33     build(tr*2,l,mid);
     34     build(tr*2+1,mid+1,r);
     35     tree[tr].minn=min(tree[tr*2].minn,tree[tr*2+1].minn);
     36     tree[tr].mid=(tree[tr].l+tree[tr].r)>>1;
     37     tree[tr].sum=tree[tr*2].sum+tree[tr*2+1].sum;
     38 }
     39 void change(int tr,int l,int r,int data)
     40 {
     41     if (tree[tr].l==l&&r==tree[tr].r)
     42     {
     43         tree[tr].lazy+=data;
     44         if (tree[tr].minn<=tree[tr].lazy)
     45         {
     46             if (tree[tr].l==tree[tr].r)
     47             {
     48                 tree[tr].sum=0;
     49                 tree[tr].minn=0x3f3f3f3f;
     50                 tree[tr].lazy=0;
     51             }
     52             else 
     53             {
     54                 change(tr*2,tree[tr].l,tree[tr].mid,tree[tr].lazy);
     55                 change(tr*2+1,tree[tr].mid+1,tree[tr].r,tree[tr].lazy);
     56                 tree[tr].lazy=0;
     57                 tree[tr].sum=tree[tr*2].sum+tree[tr*2+1].sum;
     58                 tree[tr].minn=min(tree[tr*2].minn-tree[tr*2].lazy,tree[tr*2+1].minn-tree[tr*2+1].lazy);
     59             }
     60         }
     61         return;
     62     }
     63     if (tree[tr].lazy)
     64     {
     65         change(tr*2,tree[tr].l,tree[tr].mid,tree[tr].lazy);
     66         change(tr*2+1,tree[tr].mid+1,tree[tr].r,tree[tr].lazy);
     67         tree[tr].lazy=0;
     68     }
     69     if (r<=tree[tr].mid) change(tr*2,l,r,data);
     70     else if (l>tree[tr].mid) change(tr*2+1,l,r,data);
     71     else
     72     {
     73         change(tr*2,l,tree[tr].mid,data);
     74         change(tr*2+1,tree[tr].mid+1,r,data);
     75     }
     76     tree[tr].minn=min(tree[tr*2].minn-tree[tr*2].lazy,tree[tr*2+1].minn-tree[tr*2+1].lazy);
     77     tree[tr].sum=tree[tr*2].sum+tree[tr*2+1].sum;
     78 }
     79 
     80 int ask(int tr,int l,int r)
     81 {
     82     if (tree[tr].l==l&&tree[tr].r==r) return tree[tr].sum;
     83     int mid=(tree[tr].l+tree[tr].r)/2;
     84     if (r<=mid) return ask(tr*2,l,r);
     85     else if (l>mid) return ask(tr*2+1,l,r);
     86     else return ask(tr*2,l,mid)+ask(tr*2+1,mid+1,r);
     87 }
     88 
     89 void dfs(int a)
     90 {
     91     first[a]=++tim;
     92     v[tim]=a;
     93     for (int i=head[a];i!=-1;i=next[i])
     94     dfs(ver[i]);
     95     second[a]=tim;
     96 }
     97 
     98 int main()
     99 {
    100     freopen("alone.in","r",stdin);
    101     freopen("alone.out","w",stdout);
    102     cin>>n;
    103     memset(head,-1,sizeof(head));
    104     for (int i=1;i<=n;i++)
    105     scanf("%d%d",&h[i],&a),add(a,i);
    106     h[0]=0x3f3f3f3f;
    107     dfs(0);
    108     cin>>m;
    109     build(1,1,n+1);
    110     for (int i=1;i<=m;i++)
    111     {
    112         scanf("%d",&a);
    113         if (a==1)
    114         {
    115             scanf("%d%d",&b,&c);
    116             if (first[b]!=second[b]) change(1,first[b]+1,second[b],c);
    117         }
    118         else
    119         {
    120             scanf("%d",&b);
    121             if (first[b]!=second[b]) printf("%d
    ",ask(1,first[b]+1,second[b]));
    122             else printf("0
    ");
    123         }
    124     }
    125     fclose(stdin);
    126     fclose(stdout);
    127     return 0;
    128 }
    View Code
  • 相关阅读:
    排序
    git常用操作_分支合并_新建工程等
    ibatis 中调用存储过程
    IDEA试用期结束激活问题
    kafka本地工程的调用说明
    python yield 和 yield from用法总结
    ubuntu14.06 Lts开启ssh服务
    QT-1-环境搭建QT5.4.1&MinGW4.9.1
    虚拟机Ping不通主机解决
    CRC类(处理ITU表)
  • 原文地址:https://www.cnblogs.com/Beckinsale/p/7401598.html
Copyright © 2011-2022 走看看