zoukankan      html  css  js  c++  java
  • 20160727noip模拟赛zld

    image

    首先最优策略肯定是这样的:我们取出这个序列中的最大值,然后将整个序列分为左右两部分, 那么我们一定先把左右两部分合起来然后再与这个值合并

    那么我们可以得出一个基于最值查询(rmq)的nlog_{2}{n}的算法,但是zld上次出10^6级别的题目时,卡掉了nlog_{2}{n}的算法

    所以我们想一个优秀一点的做法,发现这个过程可以简单的用一个单调队列维护,维护单调减的单调栈,就可以O(n)解决这个问题

    我们仔细观察会发现更优秀的做法,答案一定是sum_{i=1}^{n-1}max(a_{i},a_{i+1}),但是这个玩意我不会证明

    int a[2333333];
    int main(){
        FO(seq);
        RI(n); 
        ll ans=0;
        FOR1(i,n)a[i]=gi;
        FOR1(i,n-1){
            ans+=max(a[i],a[i+1]);
        }
        cout<<ans;
    }

    T2

    image

    image

    首先观察发现关于异或的性质

    (2k)Xor(2k+1)=1

    那么如果kge4,肯定能凑成1^1=0

    对于k=1 答案显然是l

    对于k=2

    如果l+l&1!=r那么根据性质答案为1

    否则答案是l^r和l中最小的一个

    对于k=3,我们肯定能构造出为1的答案,那么考虑能不能构造出为0的

    如果有三个数,异或为0

    可能满足

    1100
    1011
    0111
    这样的模式,如果lr区间不能满足这样的模式,那么答案肯定是1
    不要和我提多组数据 懒得改了
    #include<map>
    #include<stack>
    #include<queue>
    #include<cstdio>
    #include<string>
    #include<vector>
    #include<cstring>
    #include<complex>
    #include<iostream>
    #include<assert.h>
    #include<algorithm>
    using namespace std;
    #define pb push_back
    #define inf 1001001001
    #define infll 1001001001001001001ll
    #define FOR0(i,n) for(int (i)=0;(i)<(n);++(i))
    #define FOR1(i,n) for(int (i)=1;(i)<=(n);++(i))
    #define mp make_pair
    #define pii pair<int,int>
    #define ll long long
    #define ld double
    #define vi vector<int>
    #define SZ(x) ((int)((x).size()))
    #define fi first
    #define se second
    #define RI(n) int (n); scanf("%d",&(n));
    #define RI2(n,m) int (n),(m); scanf("%d %d",&(n),&(m));
    #define RI3(n,m,k) int (n),(m),(k); scanf("%d %d %d",&(n),&(m),&(k));
    template<typename T,typename TT> ostream& operator<<(ostream &s,pair<T,TT> t) {return s<<"("<<t.first<<","<<t.second<<")";}
    template<typename T> ostream& operator<<(ostream &s,vector<T> t){FOR0(i,sz(t))s<<t[i]<<" ";return s; }
    #define dbg(vari) cerr<<#vari<<" = "<<(vari)<<endl
    #define all(t) t.begin(),t.end()
    #define FEACH(i,t) for (typeof(t.begin()) i=t.begin(); i!=t.end(); i++)
    #define TESTS RI(testow)while(testow--)
    #define FORZ(i,a,b) for(int (i)=(a);(i)<=(b);++i)
    #define FORD(i,a,b) for(int (i)=(a); (i)>=(b);--i)
    #define gmax(a,b) (a)=max((a),(b))
    #define gmin(a,b) (a)=min((a),(b))
    #define ios0 ios_base::sync_with_stdio(0)
    using namespace std;
    #define Ri register int
    #define gc getchar()
    #define il inline
    il ll read(){
        bool f=true;
        ll x=0;char ch;
        while(!isdigit(ch=gc))if(ch=='-')f=false;
        while(isdigit(ch)){x=(x<<1)+(x<<3)+ch-'0';ch=gc;}
        return f?x:-x;
    }
    #define gi read()
    #define FO(x) freopen(#x".in","r",stdin),freopen(#x".out","w",stdout);
    ll l,r,ans,cur;
    int k,cc,cnt;
    bool ac[4],cho[4];
    void exh4(){
        ll ans=infll;
        FOR1(i,15){
            cur=cnt=0;
            FOR0(j,4) cho[j]=false;
            FOR0(j,4) 
                if(i&(1<<j)) 
                    cur^=l+j,cho[j]=true,cnt++;
            if(cur<ans){
                ans=cur;
                cc=cnt;
                FOR0(j,4) 
                    ac[j]=cho[j];
            }
        }
        printf("%lld
    %d
    ",ans,cc);
        FOR0(i,4)if(ac[i])printf("%lld%c",l+i,(--cc)?' ':'
    ');
        return;
    }
    bool poss0(){
        if(r-l<2) return false;
        ll po=1,po2;
        while((po<<1)<=r) po<<=1;
        if(l>=po) return false;
        if(r==po){
            r--;
            return poss0();
        }
        po2=po>>1;
        while(po2>0&&po+po2>r) po2>>=1;
        ll res=(po+po2)^(po+po2-1);
        if(res>=l){
            printf("0
    3
    %lld %lld %lld
    ",po+po2,po+po2-1,res);
            return true;
        }
        r=po-1;
        return poss0();
    }
    int main(){
        scanf("%lld %lld %d",&l,&r,&k);
        if(k>=4){
            if(r-l==3) exh4();
            else{
                if(l&1) l++;
                printf("0
    4
    %lld %lld %lld %lld
    ",l,l+1,l+2,l+3);
            }
            return 0;
        }
        if(k==2){
        if(r-l==1){
            if(l<(l^r)) printf("%lld
    1
    %lld
    ",l,l);
            else printf("%lld
    2
    %lld %lld
    ",l^r,l,r);
            }
            else{
                if(l&1) l++;
                printf("1
    2
    %lld %lld
    ",l,l+1);
            }
            return 0;
        }
        if(k==1){
            printf("%lld
    1
    %lld
    ",l,l);
            return 0;
        }
        if(k==3){
            if(poss0()) return 0;
            else{
                if(l&1) l++;
                  printf("1
    2
    %lld %lld
    ",l,l+1);
            }
        }
        return 0;
    }
    T3

    image

    卓神讲的太简略了 现在还是不会做

    Zld的题解

    image

  • 相关阅读:
    Linux学习笔记-Shell和命令基础
    转载 | 辗转相除法
    C语言字符数组应用示例2:用二维数组输出一个菱形图案
    C语言字符数组应用示例1:编写一个程序,将两个字符串连接起来,不用strcat函数。
    C语言字符数组超细讲解
    C语言二维数组的应用举例
    C语言二维数组超细讲解
    Java同步方法:synchronized到底锁住了谁?
    家乐的深度学习笔记「5」
    工程中的算法应用
  • 原文地址:https://www.cnblogs.com/chouti/p/5723926.html
Copyright © 2011-2022 走看看