zoukankan      html  css  js  c++  java
  • 浙大2018省赛——重现赛(The 15th Zhejiang Provincial Collegiate Programming Contest Sponsored by TuSimple)

    题目链接:http://acm.zju.edu.cn/onlinejudge/showContestProblems.do?contestId=378

    简单题就不写了。

    ============================================

    D、Sequence Swapping

    E、LIS

    一、题意  

      题目背景为LIS。现在已知$dp$数组,给定所有元素的上下界,要求构造满足条件的数组。Special Judge。

    二、思路

      不妨假设输入数据为$a[i]$。定义$c[i]$,表示:距离$a[i]$最近的且等于$a[i]-1$的元素位置。当$a[i]=1$时,那$c[i]$就随便了。$i$位置的上下界分别定义为$ub[i]$和$lb[i]$。

      接下来,枚举所有的$dp$值,最小$1$,最大$n$。对于当前枚举的值$i$,找出$i$在$a$数组中的所有出现位置(可$O(n)$时间预处理出来),对于出现位置$p$,下标为$p$处的答案应该为:

      如果$a[p]=1$,$ans[p]=max(lb[p],max{ans[j]}(p<j<=n&&a[j]=a[p]))$;

      否则,$ans[p]=max(lb[p]max{ans[j]}(p<j<=n&&a[j]=a[p]), ans[c[p]]+1)$;

      /*********************LaTeX解析不出来,难受,TT_TT*******************************/

      此外,这题的上界在此思路中是没用的。因为这种思路可保证所求答案一定在上界内。

      注意,这题卡常非常严重。清空记录位置的容器时,循环上界用$n$,别用$MAXN$。

    三、代码

      

    /********************template head********************/
    #include<bits/stdc++.h>
    using namespace std;
    #define pb(x) push_back(x)
    #define mk(x, y) make_pair(x, y)
    #define pln() putchar('\n')
    #define cln() (cout << '\n')
    #define fst first
    #define snd second
    #define MOD 1000000007LL
    typedef long long LL;
    typedef pair<int, int> PII;
    typedef pair<LL, LL> PLL;
    const int MAXN = 1e5 + 10;
    
    template <class T> inline void read(T &x) {
        int t;
        bool flag = false;
        while((t = getchar()) != '-' && (t < '0' || t > '9')) ;
        if(t == '-') flag = true, t = getchar(); x = t - '0';
        while((t = getchar()) >= '0' && t <= '9') x = x * 10 + t - '0';
        if(flag) x = -x;
    }
    
    template<class T> T gcd(T a, T b) {
        return b ? gcd(b, a % b) : a;
    }
    
    template<class T> T modpow(T a, T x, T mod) {
        T res = T(1);
        while(x > 0) {
            if(x & 1)res = (res * a) % mod;
            a = (a * a) % mod;
            x >>= 1;
        }
        return res;
    }
    /********************template head********************/
    
    
    int n, a[MAXN], b[MAXN], c[MAXN], lb[MAXN], ub[MAXN], ans[MAXN];
    vector<int> vs[MAXN];
    int main() {
    #ifndef ONLINE_JUDGE
       // freopen("input.txt", "r", stdin);
    #endif // ONLINE_JUDGE
        int T;
        for(read(T); T--;) {
            read(n);
            for(int i = 1; i <= n; ++i)vs[i].clear();
            for(int i = 1; i <= n; ++i) {
                read(a[i]);
                b[a[i]] = i;
                c[i] = b[a[i] - 1];
                vs[a[i]].pb(i);
            }
            for(int i = 1; i <= n; ++i)read(lb[i]), read(ub[i]);
            for(int i = 1; i <= n; ++i) {
                int yb = -1;
                for(int j = vs[i].size() - 1; j >= 0; --j) {
                    int p = vs[i][j];
                    ans[p] = max(lb[p], yb);
                    if(a[p] != 1)ans[p] = max(ans[p], ans[c[p]] + 1);
                    yb = ans[p];
                }
            }
            for(int i = 1; i <= n; ++i)printf("%d%c", ans[i], i == n ? '\n' : ' ');
        }
        return 0;
    }

    F、Now Loading!!!

    一、思路

      预处理出$\frac{a[i]}{j}(1 \le i \le n, 1 \le j \le 30)$的前缀和。注意$j$的最大值,如果前缀和的类型为long long,$j$的上界取为$31$,会MLE。当然,可以用int,然后,在预处理前缀和的时候对$10^9$取模。但是,要注意,在求区间和的时候,要保证区间和为正。

      然后,倍增+二分即可。

    二、代码实现

    /*--------------template head----------------*/
    #include<bits/stdc++.h>
    using namespace std;
    #define pb(x) push_back(x)
    #define mk(x, y) make_pair(x, y)
    #define pln() putchar('\n')
    #define cln() (cout << '\n')
    #define fst first
    #define snd second
    #define MOD 1000000000LL
    typedef long long LL;
    typedef pair<int, int> PII;
    typedef pair<LL, LL> PLL;
    const int MAXN = 1e5 + 10;
    
    template <class T> inline void read(T &x) {
        int t;
        bool flag = false;
        while((t = getchar()) != '-' && (t < '0' || t > '9')) ;
        if(t == '-') flag = true, t = getchar(); x = t - '0';
        while((t = getchar()) >= '0' && t <= '9') x = x * 10 + t - '0';
        if(flag) x = -x;
    }
    
    template<class T> T gcd(T a, T b){
        return b ? gcd(b, a % b) : a;
    }
    
    template<class T> T modpow(T a, T x, T mod){
        T res = T(1);
        while(x > 0){
            if(x & 1)res = (res * a) % mod;
            a = (a * a) % mod;
            x >>= 1;
        }
        return res;
    }
    /*--------------template head----------------*/
    int a[500010],n,m;
    LL data[31][500010];
    LL qzh(int ai,int aa,int b)
    {
        return data[ai][b]-data[ai][aa-1];
    }
    int main() {
        //freopen("input.txt", "r", stdin);
        int T;
        LL p;
        cin>>T;
        while(T--)
        {
            LL ans=0;
            cin>>n>>m;
            for(int i=1;i<=n;i++) read(a[i]);
            sort(a+1,a+n+1);
            for(int i=1;i<=30;i++)
            {
                data[i][1]=a[1]/i;
                for(int j=2;j<=n;j++) data[i][j]=data[i][j-1]+a[j]/i;
            }
            for(int i=1;i<=m;i++)
            {
                LL sum=0;
                read(p);
                int bg=1,ed=1;
                LL ap=1;
                int qz=0;
                while(++qz)
                {
                   if(ap>a[n]) break;
                   ap*=p;
                   ed=upper_bound(a+1,a+1+n,ap)-a;
                   sum=sum+qzh(qz,bg,ed-1);
                   //cout<<ap<<" "<<bg<<" "<<ed-1<<endl;
                   sum%=MOD;
                   bg=ed;
                }
                sum*=i;
                sum%=MOD;
                ans=ans+sum;
                ans%=MOD;
            }
            cout<<ans<<"\n";
        }
        return 0;
    }
  • 相关阅读:
    bzoj 5092: [Lydsy1711月赛]分割序列
    bzoj1173: [Balkan2007]Point
    bzoj1536: [POI2005]Akc- Special Forces Manoeuvres
    bzoj2178: 圆的面积并
    bzoj1043 下落的圆盘
    bzoj2674 Attack
    bzoj1201: [HNOI2005]数三角形
    bzoj3135: [Baltic2013]pipesd
    bzoj1760 [Baltic2009]Triangulation
    bzoj3136
  • 原文地址:https://www.cnblogs.com/dowhile0/p/8982401.html
Copyright © 2011-2022 走看看