zoukankan      html  css  js  c++  java
  • 【解题报告】13级个人结业赛(一) ——涨姿势专场

    A.优化(1)

    前缀和优化。

    预处理出a数组0~i的和,然后每次取b[i]~i的和时取出sum[i]-sum[b[i]-1]。

     1 #include<stdio.h>
     2 #include<math.h>
     3 #include<string.h>
     4 #include<iostream>
     5 #include<algorithm>
     6 #include<map>
     7 #include<set>
     8 #include<queue>
     9 #include<stack>
    10 using namespace std;
    11 typedef long long ll;
    12 ll f2(ll a[],ll b[],ll len)
    13 {
    14     ll ans=0,i,j;
    15     for(i=0;i<len;i++)
    16     {
    17         if(i!=0) a[i]+=a[i-1];
    18         if(b[i]!=0) ans+=a[i]-a[b[i]-1];
    19         else ans+=a[i];
    20     }
    21     return ans;
    22 }
    23 ll a[1000005],b[1000005],len;
    24 int main()
    25 {
    26     int i;
    27     while(scanf("%lld",&len)!=EOF)//len<1000000
    28     {
    29         for(i=0;i<len;i++) scanf("%lld",&a[i]);//-1000000000<=a[i]<=1000000000
    30         for(i=0;i<len;i++) scanf("%lld",&b[i]);//0<=b[i]<=i
    31         printf("%lld
    ",f2(a,b,len));
    32     }
    33     return 0;
    34 }
    View Code

    B.优化(2)

    离线处理。读入所有的点和查询,按x坐标排序,然后从小到大维护最大y。碰到点时更新最大y,碰到查询时将查询结果保存起来。处理完所有查询后按原来输入的顺序输出答案。

     1 #include<stdio.h>
     2 #include<math.h>
     3 #include<string.h>
     4 #include<iostream>
     5 #include<algorithm>
     6 #include<map>
     7 #include<set>
     8 #include<queue>
     9 #include<stack>
    10 #define FOR(i,n) for(i=0;i<(n);i++)
    11 #define CLR(a) memset(a,0,sizeof(a))
    12 #define CIN(a) scanf("%d",&a)
    13 typedef long long ll;
    14 using namespace std;
    15 pair<int,int> a[200005];
    16 int ans[100005];
    17 int main()
    18 {
    19     int n,q,i,x;
    20     while(scanf("%d",&n)!=EOF)
    21     {
    22         for(i=0;i<n;i++) scanf("%d%d",&a[i].first,&a[i].second);
    23         scanf("%d",&q);
    24         for(i=1;i<=q;i++)
    25         {
    26             scanf("%d",&a[n].first);
    27             a[n].second=-i;
    28             n++;
    29         }
    30         sort(a,a+n);
    31         int an=-1;
    32         for(i=0;i<n;i++)
    33         {
    34             if(a[i].second<0) ans[-a[i].second]=an;
    35             else an=max(an,a[i].second);
    36         }
    37         for(i=1;i<=q;i++)
    38         {
    39             printf("%d
    ",ans[i]);
    40         }
    41     }
    42     return 0;
    43 }
    View Code

    C.优化(3)

    详看代码。 

     1 #include<stdio.h>
     2 #include<math.h>
     3 #include<string.h>
     4 #include<iostream>
     5 #include<algorithm>
     6 #include<map>
     7 #include<set>
     8 #include<queue>
     9 #include<stack>
    10 #define FOR(i,n) for(i=0;i<(n);i++)
    11 #define CLR(a) memset(a,0,sizeof(a))
    12 #define CIN(a) scanf("%d",&a)
    13 typedef long long ll;
    14 using namespace std;
    15 ll a[1000005]; //a[i]=x^(i*1e12)=x^((i-1)*1e12)*x^1e12=a[i-1]*a[1]
    16                //a[1]=b[1e6]
    17 ll b[1000005]; //b[i]=x^(i*1e6) =x^((i-1)*1e6) *x^1e6 =b[i-1]*b[1]
    18                //b[1]=c[1e6]
    19 ll c[1000005]; //c[i]=x^i=c[i-1]*c[1]
    20                //c[1]=x;
    21 //x^y=a[y/1e12]*b[y%1e12/1e6]*c[y%1e6];
    22 ll e12=1000000000000LL;
    23 ll e6=1000000LL;
    24 ll nextrandom(ll y,ll MOD)
    25 //随机数生成器,不用改
    26 //之所以要随机数生成器,是因为后台没办法上传太大的文件
    27 //产生的随机数是为了测试代码效率,所有产生的随机数在[1,10^18]内
    28 {
    29     y=y*y*MOD;
    30     if(y&1LL<<63) y=~y+1;
    31     return y%1000000000000000000LL+1;
    32 }
    33 ll init(ll a[],ll x,ll MOD)
    34 {
    35     a[0]=1;
    36     a[1]=x;
    37     for(int i=2;i<=e6;i++)
    38     {
    39         a[i]=(a[i-1]*x)%MOD;
    40     }
    41     return a[e6];
    42 }
    43 ll f3(ll x,ll y,ll MOD)
    44 {
    45     return (a[y/e12]*b[y%e12/e6])%MOD*c[y%e6]%MOD;
    46 }
    47 int main()
    48 {
    49     ll x,q,y,MOD=1000000007LL,z,ans;
    50     while(scanf("%lld",&x)!=EOF)//x<=10^9
    51     {
    52         init(a,init(b,init(c,x,MOD),MOD),MOD);
    53         scanf("%lld%lld",&q,&y);//q<=5000000,y<=10^18
    54         ans=0;
    55         while(q--)
    56         {
    57             ans=(ans+f3(x,y,MOD))%MOD;
    58             y=nextrandom(y,MOD);
    59         }
    60         printf("%lld
    ",ans);
    61     }
    62     return 0;
    63 }
    View Code

    D.求众数

    用map保存每个数出现的次数,用一个set保存出现次数最多的书,并保存当前出现次数最多的次数,每次添加一个数时取出这个数原本出现的次数,将它加一然后和和原本的最多的次数比较,如果相同则将这个数添加进set,如果超过了原本的次数则清空原本的set然后将这个数添加到set内,同时更新最多次数。查询时遍历一遍set输出。

     1 #include<stdio.h>
     2 #include<math.h>
     3 #include<string.h>
     4 #include<iostream>
     5 #include<algorithm>
     6 #include<map>
     7 #include<set>
     8 #include<queue>
     9 #include<stack>
    10 #define FOR(i,n) for(i=0;i<(n);i++)
    11 #define CLR(a) memset(a,0,sizeof(a))
    12 #define CIN(a) scanf("%d",&a)
    13 typedef long long ll;
    14 using namespace std;
    15 /*
    16 操作1:插入一个数
    17 操作2:计算众数
    18 */
    19 map<int,int> m;
    20 set<int> s;
    21 int ma;
    22 void in(int x){
    23     map<int,int>::iterator it=m.find(x);
    24     if(it!=m.end()){
    25         it->second++;
    26         if(it->second > ma){
    27             s.clear();
    28             s.insert(x);
    29             ma=it->second;
    30         }else if(it->second==ma){
    31             s.insert(x);
    32         }
    33     }else{
    34         m[x]=1;
    35         if(ma<=1) s.insert(x);
    36     }
    37 }
    38 void get(){
    39     set<int>::iterator it;
    40     for(it=s.begin();it!=s.end();it++){
    41         if(it!=s.begin()) printf(" ");
    42         printf("%d",*it);
    43     }
    44     printf("
    ");
    45 }
    46 int main(){
    47     int n,x,z;
    48     while(scanf("%d",&n)!=EOF){//n<=20w
    49         ma=-1;
    50         s.clear();
    51         m.clear();
    52         while(n--){
    53             scanf("%d",&z);
    54             if(z==1){//插入一个数
    55                 scanf("%d",&x);//int范围内
    56                 in(x);
    57             }else if(z==2){//求众数
    58                 get();
    59             }
    60         }
    61     }
    62     return 0;
    63 }
    View Code

    E.求中位数

    用一个大顶堆和一个小顶堆保存整个数组,维护大顶堆内的所有数小于等于小顶堆内的所有数。如果总数是偶数时,维护两个堆内的元素个数相等,否则大顶堆内数字的个数比小顶堆内多一。查询时,如果大顶堆和小顶堆内的元素个数相同,则分别取出两个堆顶元素相加除以2,否则取出大顶堆的堆顶元素。

     1 #include<stdio.h>
     2 #include<math.h>
     3 #include<string.h>
     4 #include<iostream>
     5 #include<algorithm>
     6 #include<map>
     7 #include<set>
     8 #include<queue>
     9 #include<stack>
    10 #define FOR(i,n) for(i=0;i<(n);i++)
    11 #define CLR(a) memset(a,0,sizeof(a))
    12 #define CIN(a) scanf("%d",&a)
    13 typedef long long ll;
    14 using namespace std;
    15 priority_queue<int> p1;
    16 priority_queue<int,vector<int>,greater<int> >  p2;
    17 void in(int x){
    18     if(p1.size()==p2.size()){
    19         p2.push(x);
    20         p1.push(p2.top());
    21         p2.pop();
    22     }else{
    23         p2.push(x);
    24         if(p2.top()<p1.top())
    25         {
    26             p1.push(p2.top());
    27             p2.pop();
    28             p2.push(p1.top());
    29             p1.pop();
    30         }
    31     }
    32 }
    33 void mid(){
    34     if(p1.size()==p2.size()){
    35         if(((ll)p1.top()+p2.top())%2==0) printf("%d
    ",(int)(((ll)p1.top()+p2.top())/2));
    36         else printf("%.1lf
    ",(1.0*p1.top()+p2.top())/2);
    37     }else printf("%d
    ",p1.top());
    38 }
    39 int main(){
    40     int n,z,x;
    41     while(scanf("%d",&n)!=EOF){//n<=20w;
    42         while(!p1.empty()) p1.pop();
    43         while(!p2.empty()) p2.pop();
    44         while(n--){
    45             scanf("%d",&z);
    46             if(z==1){//插入一个数
    47                 scanf("%d",&x);//int范围内
    48                 in(x);
    49             }else if(z==2){//查询中位数
    50                 mid();
    51             }
    52         }
    53     }
    54     return 0;
    55 }
    View Code

    F.求平均数

    两个树状数组维护集合的总和合数量。查询时取出区间值相除。要注意的是总和可能是负数,不要直接拿去求最大公约数。不然可能求出来的公约数是负数。

     1 #include<stdio.h>
     2 #include<math.h>
     3 #include<string.h>
     4 #include<iostream>
     5 #include<algorithm>
     6 #include<map>
     7 #include<set>
     8 #include<queue>
     9 #include<stack>
    10 #define FOR(i,n) for(i=0;i<(n);i++)
    11 #define CLR(a) memset(a,0,sizeof(a))
    12 #define CIN(a) scanf("%d",&a)
    13 typedef long long ll;
    14 using namespace std;
    15 #define MAXLEN 100005
    16 int s[MAXLEN],num[MAXLEN],n;
    17 int Lowbit(int x){return x&(-x);}
    18 int GCD(int a,int b){return b?GCD(b,a%b):a;}
    19 int sum(int c[],int end){
    20     int sum=0;
    21     while(end>0){
    22         sum+=c[end];
    23         end-=Lowbit(end);
    24     }
    25     return sum;
    26 }
    27 void update(int c[],int pos,int num){
    28     while(pos<=n){
    29         c[pos]+=num;
    30         pos+=Lowbit(pos);
    31     }
    32 }
    33 void print(int a,int b){
    34     if(!b) {printf("Error!
    ");return;}
    35     int gcd=GCD(a,b);
    36     printf("%d/%d
    ",a/gcd,b/gcd);
    37 }
    38 int main(){
    39     int z,q,a,b;
    40     while(scanf("%d%d",&n,&q)!=EOF){
    41         memset(s,0,sizeof(s));
    42         memset(num,0,sizeof(num));
    43         while(q--){
    44             scanf("%d%d%d",&z,&a,&b);
    45             if(z==1){
    46                 update(s,a,b);
    47                 update(num,a,1);
    48             }else{
    49                 int S=sum(s,b)-sum(s,a-1);
    50                 int n=sum(num,b)-sum(num,a-1);
    51                 if(S<0){
    52                     printf("-");
    53                     print(-S,n);
    54                 }else print(S,n);
    55             }
    56         }
    57     }
    58     return 0;
    59 }
    View Code

    G.割绳子问题

    二分枚举绳子的长度,每次判断能否得到k个这样的长度的绳子。

     1 #include <stdio.h>
     2 #include <string.h>
     3 #include <math.h>
     4 #include <algorithm>
     5 using namespace std;
     6 int N,K,num[10005];
     7 long long sum;
     8 int Judge(int Num)
     9 {
    10     int Sign=0,i;
    11     for(i=0;i<N;i++)
    12     {
    13         Sign+=(num[i]/Num);
    14     }
    15     if(Sign>=K) return 1;
    16     return 0;
    17 }
    18 int main()
    19 {
    20     int i;
    21    // freopen("0.in","r",stdin);
    22    // freopen("0.out","w",stdout);
    23     while(scanf("%d%d",&N,&K)!=EOF)
    24     {
    25         sum=0;
    26         for(i=0;i<N;i++)
    27         {
    28             scanf("%d",&num[i]);
    29             sum+=num[i];
    30         }
    31         sum/=K;
    32         int L=0,R=sum,Mid;
    33         while((R-L)>=1)
    34         {
    35             if(R-1==L)
    36             {
    37                 if(Judge(R)) {L=R;break;}
    38                 else if(Judge(L)){L=L;break;}
    39             }
    40             else
    41             {
    42                 Mid = (L+R)/2;
    43                 if(Judge(Mid)) L=Mid;
    44                 else R=Mid;
    45             }
    46  
    47         }
    48       //  printf("%.2f=>%d
    ",L,(int)(L+EXP));
    49          printf("%d
    ",L);
    50     }
    51     return 0;
    52 }
    View Code
  • 相关阅读:
    清除所有缓存命令
    web前端工程师面试技巧 常见问题解答
    Web前端开发面试技巧
    JavaScript
    JavaScript Cookie
    JavaScript 计时事件
    javascript 弹窗
    JavaScript Window Navigator
    JavaScript Window History
    JavaScript Window Location
  • 原文地址:https://www.cnblogs.com/syiml/p/4510376.html
Copyright © 2011-2022 走看看