[bzoj3489]A simple rmq problem

  本题既不是rmq也不会simple(对我这种蒟蒻而言)

  一开始只能想到树套树套树TAT然后看了看数据范围果断滚去膜拜题解。

  然后才知道预先排序一下可以弄掉一个log。不过得写可持久化线段树套可持久化线段树。。

  然后愉悦的开码了。。。感人的是竟然不用调。。。更感人的是交上去直接tle了。

  然后从网上找了别人的代码(方法一样)发现同样的数据我要跑6s+。。标称只要2s+。。

  之后各种卡常还是慢了一倍TAT。。。最后自己写个max函数就和标程一样快了TAT这几天怎么总是出些奇怪的状况QAQ。

  本来故事到这里就应该结束了。。等评测的时候连标题都想好了:“一个max函数引发的惨剧”

  然而交上去还是tle了(掀桌。。。然后发现标程也tle了。。。

  然后想起一开始的时候标程数组范围开小。。在看了下hint。。果然出题人把数据加强了不少。

  大概结局就是写树套树的都tle了。。。。。。。。。。。。。。。。。老板来一打刀片?

直接贴tle的代码

 1 #include<cstdio>
 2 #include<iostream>
 3 #include<cstring>
 4 #include<algorithm>
 5 using namespace std;
 6 const int maxn=100233;
 7 struct poi{
 8     int pos,pr,af,num;
 9 }a[maxn];
10 int pr[maxn],af[maxn];
11 int rt_out[maxn],rt[maxn*18],lc[maxn*18],rc[maxn*18],tt;
12 int mx[400*maxn],l[400*maxn],r[400*maxn],tot;
13 int i,j,n,m,L,R,lastans,v,v1;
14
15 int ra;char rx;
16 inline int read(){
17     rx=getchar(),ra=0;
18     while(rx<‘0‘||rx>‘9‘)rx=getchar();
19     while(rx>=‘0‘&&rx<=‘9‘)ra*=10,ra+=rx-48,rx=getchar();return ra;
20 }
21 char qaq[7];int len;
22 inline void outx(int x){
23     if(!x){puts("0");return;}
24     while(x)qaq[len++]=x%10,x/=10;
25     while(len)putchar(qaq[--len]+‘0‘);putchar(‘\n‘);
26 }
27 inline int max(int x,int y){return x<y?y:x;}
28
29
30 inline void ins(int pre,int &x,int L,int R){
31     x=++tot,mx[x]=mx[pre];
32     if(a[i].num>mx[x])mx[x]=a[i].num;
33     if(L==R)return;
34     register int mid=(L+R)>>1;
35     if(v<=mid)r[x]=r[pre],ins(l[pre],l[x],L,mid);
36     else l[x]=l[pre],ins(r[pre],r[x],mid+1,R);
37 }
38 int zs;
39 inline int getmx(int x,int L,int R,int c,int d){
40     if(!x)return 0;
41     if(c<=L&&d>=R)return mx[x];register int mid=(L+R)>>1;
42     if(c>mid)return getmx(r[x],mid+1,R,c,d);else
43     if(d<=mid)return getmx(l[x],L,mid,c,d);else
44     return max(getmx(l[x],L,mid,c,d),getmx(r[x],mid+1,R,c,d));
45
46 }
47
48
49
50
51 inline void insert(int pre,int&x,int L,int R){
52     x=++tt,ins(rt[pre],rt[x],1,n);
53     if(L==R)return;
54     register int mid=(L+R)>>1;
55     if(v1<=mid)rc[x]=rc[pre],insert(lc[pre],lc[x],L,mid);
56     else lc[x]=lc[pre],insert(rc[pre],rc[x],mid+1,R);
57 }
58 inline int query(int x,int l,int r,int c,int d){
59     if(!x)return 0;
60     if(c<=l&&d>=r)return getmx(rt[x],1,n,L,R);
61     register int mid=(l+r)>>1;
62     if(c>mid)return query(rc[x],mid+1,r,c,d);
63     else return max(getmx(rt[rc[x]],1,n,L,R),query(lc[x],l,mid,c,d));
64 }
65
66
67
68
69 bool cmp(poi a,poi b){return a.pr<b.pr;}
70 int main(){
71     n=read(),m=read();
72     for(i=1;i<=n;i++)a[i].pos=i,a[i].pr=pr[a[i].num=read()],pr[a[i].num]=i;
73     for(i=n;i;i--)a[i].af=af[a[i].num]?af[a[i].num]:(n+1),af[a[i].num]=i;
74     sort(a+1,a+1+n,cmp);
75     for(i=1;i<=n;i++)v=a[i].pos,v1=a[i].af,insert(rt_out[i-1],rt_out[i],1,n+1);
76     for(i=1;i<=m;i++){
77         L=read()+lastans,R=read()+lastans;
78         if(L>=n)L%=n;if(R>=n)R%=n;
79         L++,R++;if(L>R)swap(L,R);
80         register int l=1,r=n,mid;
81         for(;l<r;a[mid].pr<L?(l=mid):(r=mid-1)) mid=(l+r+1)>>1;
82         lastans=query(rt_out[l],1,n+1,R+1,n+1);
83         outx(lastans);
84     }
85     return 0;
86 }

时间: 2024-10-03 14:01:00

[bzoj3489]A simple rmq problem的相关文章

【kd-tree】bzoj3489 A simple rmq problem

Orz zyf教给蒟蒻做法 蒟蒻并不会这题正解……(可持久化树套树?...Orz 对于每个点,我们可以求出pre[i],nex[i],那么询问的答案就是:求max (a[i]),其中 i 满足(pre[i]<ql and nex[i]>qr and i∈[ql,qr]) 然后我们以(i,pre[i],nex[i])为坐标……将所有点抽象到三维空间中,每次查询就相当于是一次区域求最值! 这题我的感受: 因为前面做了两道区域求和的……然后思路不由自主又代入到搞[子树最大值]来更新答案……然而忘记了

bzoj3489: A simple rmq problem (主席树)

//========================== 蒟蒻Macaulish:http://www.cnblogs.com/Macaulish/  转载要声明! //========================== 说好的“因为是OJ上的题,就简单点好了.”呢? 一开始看不懂,不会写. 然后跪了一个晚上决定看云的题解&……似乎是主席树套主席树!吓傻,还开了40000000的数组.然后一交tle…… 然后p是不可能玩常数的. 找不到其他做法. 然后找到了神牛dwjshift,好心地提供了题

bzoj3489 A simple rmq problem 可持久化树套树

先预处理出两个个数组pre,next.pre[i]表示上一个与i位置数字相同的位置,若不存在则设为0:next[i]表示下一个与i位置数字相同的位置,若不存在则设为n+1.那么一个满足在区间[L,R]中只出现一次的数字,其pre[i]<L,next[i]>R. 这样我们可以先将pre进行排序,然后将pre可持久化,外层线段树套的是当前数字的位置i,内层线段树套的是next[i].外层线段树的节点总数是nlogn,内层线段树节点总数是nlogn^2.时间复杂度O(nlogn^2). 代码 1 #

【BZOJ3489】A simple rmq problem kd-tree

[BZOJ3489]A simple rmq problem Description 因为是OJ上的题,就简单点好了.给出一个长度为n的序列,给出M个询问:在[l,r]之间找到一个在这个区间里只出现过一次的数,并且要求找的这个数尽可能大.如果找不到这样的数,则直接输出0.我会采取一些措施强制在线. Input 第一行为两个整数N,M.M是询问数,N是序列的长度(N<=100000,M<=200000) 第二行为N个整数,描述这个序列{ai},其中所有1<=ai<=N 再下面M行,每

【BZOJ】【3489】A simple rmq problem

KD-Tree(乱搞) Orz zyf教给蒟蒻做法 蒟蒻并不会这题正解……(可持久化树套树?...Orz 对于每个点,我们可以求出pre[i],nex[i],那么询问的答案就是:求max (a[i]),其中 i 满足$ ( pre[i]<ql \ and \ nex[i]>qr\ and\ i \in [ql,qr] ) $ 然后我们以(i,pre[i],nex[i])为坐标……将所有点抽象到三维空间中,每次查询就相当于是一次区域求最值! 这题我的感受: 因为前面做了两道区域求和的……然后思路

【bzoj3489】A simple rmq problem

Portal -->bzoj3489 Solution 最近计划智力康复qwq(话说这题一年前刚刚开始写树套树的时候感觉好难啊qwq现在看其实还好也算是有进步的嘛!) 比较重要的一步是,要将"在\([l,r]\)中只出现一次"这个条件转化成"\(nxt[x]>r\)&&\(pre[x]<l\)",其中\(nxt[x]\)表示下一个出现位置\(x\)的数的位置,\(pre[x]\)表示前一个 然后我们就发现其实是有三个限制: 1.\(

【bzoj3489】 A simple rmq problem k-d树

由于某些原因,我先打了一个错误的树套树,后来打起了$k-d$.接着因不明原因在思路上被卡了很久,在今天中午蹲坑时恍然大悟...... 对于一个数字$a_i$,我们可以用一组三维坐标$(i,pre,nxt)$来表示,其中$i$表示该数字下标,$pre$表示在区间$[1,i)$中满足$a[j]=a[i]$的最大$j$,若不存在,则$pre=0$.$nxt$表示在区间$(i,n]$中满足$a[j]=a[i]$的最小$j$,若不存在,则$nxt=n+1$. 接着我们种一棵3-d树去存储这n个点.对于任意

bzoj 3489 A simple rmq problem - 线段树

Description 因为是OJ上的题,就简单点好了.给出一个长度为n的序列,给出M个询问:在[l,r]之间找到一个在这个区间里只出现过一次的数,并且要求找的这个数尽可能大.如果找不到这样的数,则直接输出0.我会采取一些措施强制在线. Input 第一行为两个整数N,M.M是询问数,N是序列的长度(N<=100000,M<=200000) 第二行为N个整数,描述这个序列{ai},其中所有1<=ai<=N 再下面M行,每行两个整数x,y, 询问区间[l,r]由下列规则产生(OIER

bzoj 3489 A simple rmq problem —— 主席树套线段树

题目:https://www.lydsy.com/JudgeOnline/problem.php?id=3489 题解:http://www.itdaan.com/blog/2017/11/24/9bc46b690756fe252e17fc3ca90aa01.html 在我挣扎一下午时 Narh 早就A了... 于是看看有何不同,发现 add  和 insert 中必须把 ls[x] = ls[y] , rs[x] = rs[y] 写在前面,而不能是修改 rs 则在那里单写一个 ls[x] =