zoukankan      html  css  js  c++  java
  • 2018 多校2 hdu 6312 6315 6318

    6312 d题

    博弈论题,Alice先删除1,则变成后手,不删1则为先手,那么无论怎样都是Alice获胜,故所有的都输出Yes

     1 #include<iostream>
     2 #include<cmath>
     3 using namespace std;
     4 
     5 int main()
     6 {
     7     int n;
     8     while(scanf("%d",&n)!=EOF) cout<<"Yes"<<endl;
     9     return 0;
    10  } 
    View Code

    6315  g题

    线段树题,本来想区间维护,后来发现不太行,就选择用单点维护,交上去t了

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cmath>
     4 #include<cstring>
     5 #include<algorithm>
     6 using namespace std;
     7 const int maxn = 1e5 + 10;
     8 double a[maxn]={0},b[maxn];
     9 int tree[400010];
    10 int grade[maxn]={0};
    11 
    12 void build(int p,int l,int r)
    13 {
    14     if(l==r){
    15         tree[p]=grade[l];
    16         return;
    17     }
    18     int mid=(l+r)/2;
    19     build(p*2,l,mid);
    20     build(p*2+1,mid+1,r);
    21     tree[p]=max(tree[p*2],tree[p*2+1]);
    22 }
    23 
    24 void change(int p,int l,int r,int x,int num)
    25 {
    26     if(l==r) {
    27         tree[p]+=num;return;
    28     }
    29     int mid=(l+r)/2;
    30     if(x<=mid) change(p*2,l,mid,x,num);
    31     else change(p*2+1,mid+1,r,x,num);
    32     tree[p]=tree[p*2]+tree[p*2+1];
    33 }
    34 
    35 
    36 int find(int p,int l,int r,int x,int y)
    37 {
    38     if(x<=l&&r<=y) return tree[p];
    39     int mid=(l+r)/2;
    40     if(y<=mid) return find(p*2,l,mid,x,y);
    41     if(x>mid) return find(p*2+1,mid+1,r,x,y);
    42     return (find(p*2,l,mid,x,mid)+find(p*2+1,mid+1,r,mid+1,y));
    43  }
    44 
    45 
    46 
    47 int main()
    48 {
    49     int n,q,x,y,c;
    50     char str[10];
    51     scanf("%d %d",&n,&q);
    52     for(int i=1;i<=n;i++){
    53         scanf("%lf",&b[i]);
    54     }
    55     build(1,0,n-1);
    56 
    57     while(q--){
    58         scanf("%s %d %d",str,&x,&y);
    59         if(strcmp(str,"add")==0){
    60             for(int i=x;i<=y;i++){
    61 a[i]++;
    62                 c=floor(a[i]/b[i]);
    63                 if(c!=grade[i]) {
    64                     int f = c-grade[i];
    65                     grade[i]=c;
    66                     change(1,1,n,i,f);
    67                 }
    68             }
    69         }
    70         else if(strcmp(str,"query")==0){
    71             int cnt = find(1,1,n,x,y);
    72             cout<<cnt<<endl;
    73         }
    74     }
    75     return 0;
    76 
    77 }
    View Code

    正解:用两个线段树

    一个用来记录最小的那个,还有多少比值之和就会再加1的值

    一个用来记录比值之和

    晚上补代码

     1 #include <iostream>
     2 #include <cstdio>
     3 #include <cmath>
     4 #include <cstring>
     5 #include <algorithm>
     6 #define maxn 100005
     7 using namespace std;
     8 typedef long long ll;
     9 struct Tree{
    10     ll sum,valb,minn,add;
    11 }tr[maxn*4];
    12 int n,q;
    13 int a[maxn],b[maxn];
    14 void push_up(int rt){
    15     tr[rt].minn=min(tr[rt*2].minn,tr[rt*2+1].minn);
    16     tr[rt].sum=tr[rt*2].sum+tr[rt*2+1].sum;
    17 }
    18 void push_down(int rt){
    19     if(tr[rt].add){
    20         tr[rt*2].add+=tr[rt].add;
    21         tr[rt*2+1].add+=tr[rt].add;
    22         tr[rt*2].minn-=tr[rt].add;
    23         tr[rt*2+1].minn-=tr[rt].add;
    24         tr[rt].add=0;
    25     }
    26 }
    27 void build(int l,int r,int rt){
    28     tr[rt].add=tr[rt].sum=0;
    29     if(l==r){
    30         tr[rt].minn=tr[rt].valb=b[l];
    31         tr[rt].sum=0;
    32         return;
    33     }
    34     int mid=(l+r)/2;
    35     build(l,mid,rt*2);
    36     build(mid+1,r,rt*2+1);
    37     push_up(rt);
    38 }
    39 void update(int L,int R,int l,int r,int rt){
    40     if(L<=l&&R>=r&&tr[rt].minn>1){
    41         tr[rt].add++;
    42         tr[rt].minn--;
    43         return;
    44     }
    45     if(l==r&&tr[rt].minn==1){
    46         tr[rt].sum++;
    47         tr[rt].minn=tr[rt].valb;
    48         tr[rt].add=0;
    49         return;
    50     }
    51     int mid=(l+r)/2;
    52     push_down(rt);
    53     if(L<=mid) update(L,R,l,mid,rt*2);
    54     if(R>mid) update(L,R,mid+1,r,rt*2+1);
    55     push_up(rt);
    56 }
    57 ll query(int L,int R,int l,int r,int rt){
    58     if(L<=l&&R>=r){
    59         return tr[rt].sum;
    60     }
    61     int mid=(l+r)/2;
    62     push_down(rt);
    63     ll ans=0;
    64     if(L<=mid) ans+=query(L,R,l,mid,rt*2);
    65     if(R>mid) ans+=query(L,R,mid+1,r,rt*2+1);
    66     return ans;
    67 }
    68 int main()
    69 {
    70     while(~scanf("%d%d",&n,&q)){
    71         for(int i=1;i<=n;i++){
    72             scanf("%d",&b[i]);
    73         }
    74         build(1,n,1);
    75         while(q--){
    76             string str;
    77             cin>>str;
    78             int l,r;
    79             scanf("%d%d",&l,&r);
    80             if(str[0]=='a'){
    81                 update(l,r,1,n,1);
    82             }
    83             else{
    84                 ll res=query(l,r,1,n,1);
    85                 printf("%lld
    ",res);
    86             }
    87         }
    88     }
    89     return 0;
    90 }
    View Code

    函数模板来自于网上(

    等我把数论概论和y总课看完了补

    6318  j题

    求逆序对,然后相乘即可

     1 #include<iostream>
     2 #include<cmath>
     3 #include<algorithm>
     4 using namespace std;
     5 const int maxn = 1e5+10;
     6 int q[maxn],tmp[maxn];
     7 
     8 long long merge_sort(int q[], int l, int r)
     9 {
    10     if (l >= r) return 0;
    11 
    12     int mid = l + r >> 1;
    13 
    14     long long res = merge_sort(q, l, mid) + merge_sort(q, mid + 1, r);
    15 
    16     int k = 0, i = l, j = mid + 1;
    17     while (i <= mid && j <= r)
    18         if (q[i] <= q[j]) tmp[k ++ ] = q[i ++ ];
    19         else
    20         {
    21             res += mid - i + 1;
    22             tmp[k ++ ] = q[j ++ ];
    23         }
    24     while (i <= mid) tmp[k ++ ] = q[i ++ ];
    25     while (j <= r) tmp[k ++ ] = q[j ++ ];
    26 
    27     for (i = l, j = 0; i <= r; i ++, j ++ ) q[i] = tmp[j];
    28 
    29     return res;
    30 }
    31 int main()
    32 {
    33     int n,x,y;
    34     long long p;
    35     while(scanf("%d %d %d",&n,&x,&y)!=EOF)
    36     {
    37         for(int i=0;i<n;i++){
    38             scanf("%d",&q[i]);
    39         }
    40         p=merge_sort(q,0,n-1);
    41         unsigned long long cnt=p*min(x,y);
    42         printf("%llu
    ",cnt);
    43     }
    44     return 0;
    45  } 
    View Code
  • 相关阅读:
    HDOJ 1207 汉诺塔II
    [转]写代码的小女孩
    POJ Subway tree systems
    HDOJ 3555 Bomb (数位DP)
    POJ 1636 Prison rearrangement (DP)
    POJ 1015 Jury Compromise (DP)
    UVA 10003
    UVA 103 Stacking Boxes
    HDOJ 3530 Subsequence
    第三百六十二、三天 how can I 坚持
  • 原文地址:https://www.cnblogs.com/moomight/p/11202811.html
Copyright © 2011-2022 走看看