【bzoj2724】[Violet 6]蒲公英 (注意:题面有毒!)

传送门:http://www.lydsy.com/JudgeOnline/problem.php?id=2724
思路:首先我要说的是,题面真的有毒啊,,,
我不停WA发现读错了题,改了还WA发现又读错了,,一直该改改,,最后卡时过,,,我也是醉了,,,种类,,编号,,傻傻分不清啊!!
代码:

#include<cstring>
#include<iostream>
#include<cstdio>
#include<string>
#include<algorithm>
#include<cmath>
#define N 40000
#define M 200
#define inf 1e9
using namespace std;
int n,m,ll,num,a[N+5],a0[N+5],b[N+5],pos[N+5],maxi,maxj,c[M+5][N],c1[M+5][N],
cnt[M+5][M+5],link1[N+5],s[N+5],t[N+5],l,r,lastans,w,ls,rs,id[N+5];
inline int getnum(){
    char c; int num;
    while (!isdigit(c = getchar()));
    num = c - '0';
    while (isdigit(c = getchar())) num = 10 * num + c - '0';
    return num;
}

void init(){
    n = getnum(); m = getnum();
    ll = ceil(sqrt(n)); num = 0;
    for (int i = 1;i <= n; ++i) a[i] = a0[i] = getnum();
    sort(a0 + 1,a0 + n + 1);
    b[0] = inf;
    for (int i = 1;i <= n; ++i) b[i] = upper_bound(a0 + 1,a0 + n + 1,a[i]) - a0 - 1;
    //for (int i = 1;i <= n; ++i) cout<<b[i]<<" ";
    //cout<<endl;
    for (int i = 1;i <= n; ++i) id[b[i]] = a[i]; 
    for (int i = 1;i <= n; ++i) pos[i] = i/ll,num = max(num,pos[i]);
    //cout<<ll<<endl;
    //for (int i  = 1;i <= n; ++i) cout<<pos[i]<<endl;
    pos[0] = -1; pos[n + 1] = -1;
    for (int i = 1;i <= n; ++i){
      if (pos[i] != pos[i - 1]) s[pos[i]] = i;
      if (pos[i] != pos[i + 1]) t[pos[i]] = i;}
    //for (int i = 0;i <= num; ++i) cout<<s[i]<<" "<<t[i]<<endl;
}

void make_it(){
    for (int i = 1;i <= n; ++i) c1[pos[i]][b[i]] ++;
    for (int i = 0;i <= num; ++i)
      if (i >= 1)
      for (int j = 1;j <= n; ++j)
         c1[i][j] += c1[i - 1][j];
    memset(cnt,0,sizeof(cnt));
    memset(link1,0,sizeof(link1));
    for (int i = num;i >= 0; --i) {
      maxi = maxj = 0;
      for (int j = i; j >= 0; --j){
        for (int k = t[j]; k >= s[j]; --k){
            c[i][b[k]] ++;
            if (c[i][b[k]] > maxi||c[i][b[k]] == maxi&&b[k] < b[maxj]) maxi = c[i][b[k]],maxj = k;  }
        cnt[j][i] = maxj; }}
}

inline int ask(int l,int r){
    memset(link1,0,sizeof(link1));
    ls = pos[l],rs = pos[r];
    maxi = 0; maxj = 0;
    if (rs - ls <= 1) {
        for (int i = r; i >= l; --i){
         ++link1[b[i]];
        if (link1[b[i]] > maxi||link1[b[i]] == maxi&&b[i] < b[maxj]) maxi = link1[b[i]],maxj = i;}}
    else {
      maxj = cnt[ls + 1][rs - 1];
      maxi = c1[rs - 1][b[maxj]] - c1[ls][b[maxj]];
      for (int i = s[rs];i <= r; ++i){
           ++link1[b[i]];
            w = link1[b[i]] + c1[rs - 1][b[i]] - c1[ls][b[i]]; 
            if (w > maxi||w == maxi&&b[i] < b[maxj]) {
              maxi = w;
              maxj = i; }}
      for (int i = t[ls];i >= l; --i){
        ++link1[b[i]];
        w = link1[b[i]] + c1[rs - 1][b[i]] - c1[ls][b[i]];
        if (w > maxi||w == maxi&&b[i] < b[maxj]) maxi = w,maxj = i;}
        }
    return maxj;
}

void DO_IT(){
    lastans = 0;
    make_it();
    for (int j = 1;j <= m; ++j){
        l = getnum(); r = getnum();
        l = (l + lastans - 1)%n + 1; r = (r + lastans - 1)%n + 1;
        //cout<<l<<" "<<r<<endl;
        //cout<<l<<" "<<r<<endl;
        if (l > r) swap(l,r);
        lastans = a[ask(l,r)];
        printf("%d\n",lastans);
    }
}

int main(){
    //freopen("a.in","r",stdin);
    //freopen("a.out","w",stdout);
    init();
    DO_IT();
    //fclose(stdin); fclose(stdout);
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值