21.5.31 t2
作者:互联网
tag:可持久化线段树,扫描线,哈希
对于 \(40%\) 的暴力,不难想到直接暴力求出所有的列表,然后nth_element
考虑拓展这个做法,实际上如果用扫瞄线求出所有列表的话,变动只有 \(O(n)\) 次,于是想到可持久化数组。注意要去重,所以再加个哈希。
求答案的时候还是使用nth_element,不过要自定义cmp函数,这个可以两个根一起线段树上二分解决(可以用哈希值判断相同/空)
复杂度 \(O(nlogn)\)
update:单哈希会被卡(即便是随机数据)
#include<bits/stdc++.h>
using namespace std;
template<typename T>
inline void Read(T &n){
char ch; bool flag=false;
while(!isdigit(ch=getchar()))if(ch=='-')flag=true;
for(n=ch^48;isdigit(ch=getchar());n=(n<<1)+(n<<3)+(ch^48));
if(flag)n=-n;
}
enum{
MAXN = 100005,
P1 = 1000000007,
base1 = 20041107,
P2 = 1000000009,
base2 = 20050711
};
int n, k;
int hs1[MAXN], hs2[MAXN];
struct node{
int lc, rc, val1, val2;
#define lc(x) t[x].lc
#define rc(x) t[x].rc
#define val1(x) t[x].val1
#define val2(x) t[x].val2
}t[MAXN*100];
int node_cnt;
void Update(int &x, int head, int tail, int loc){
if(head==tail){
if(val1(x)) x = ++node_cnt, val1(x) = val2(x) = 0;
else x = ++node_cnt, val1(x) = hs1[head], val2(x) = hs2[head];
return;
}
int mid = head+tail >> 1;
int tmpx = x; t[x=++node_cnt] = t[tmpx];
if(loc<=mid) Update(lc(x),head,mid,loc);
if(mid<loc) Update(rc(x),mid+1,tail,loc);
val1(x) = val1(lc(x))+val1(rc(x)); if(val1(x)>=P1) val1(x) -= P1;
val2(x) = val2(lc(x))+val2(rc(x)); if(val2(x)>=P2) val2(x) -= P2;
}
int ans[MAXN], len;
void print(int x, int head, int tail){
if(!x or !val1(x)) return;
if(head==tail) return ans[++len] = head, void();
// if(head==tail) return printf("%d ",head), void();
int mid = head+tail >> 1;
print(lc(x),head,mid); print(rc(x),mid+1,tail);
}
char check(int x, int y, int head, int tail, int rx, int ry){
if(head==tail) return (val1(x)!=0||val2(x)!=0)?ry!=0:!rx;
int mid = head+tail >> 1;
if(val1(lc(x))!=val1(lc(y))) return check(lc(x),lc(y),head,mid,rx||val1(rc(x))||val2(rc(x)),ry||val1(rc(y))||val2(rc(y)));
return check(rc(x),rc(y),mid+1,tail,rx,ry);
}
inline bool cmp(const int &u, const int &v){return u==v?false:check(u,v,1,n,0,0);}
typedef pair<int,int> pii;
set<pii>st;
struct upd{
int x, id;
inline bool operator <(const upd &k)const{return x<k.x;}
}q[MAXN<<1];
int qcnt;
int rts[MAXN<<1], cnt;
int main(){
// freopen("2.in","r",stdin);
// freopen("2.out","w",stdout);
Read(n); Read(k);
hs1[0] = 1; for(register int i=1; i<=n; i++) hs1[i] = 1ll*hs1[i-1]*base1%P1;
hs2[0] = 1; for(register int i=1; i<=n; i++) hs2[i] = 1ll*hs2[i-1]*base2%P2;
for(register int i=1; i<=n; i++){
qcnt++; Read(q[qcnt].x); q[qcnt].id = i;
qcnt++; Read(q[qcnt].x); q[qcnt].id = i;
}
sort(q+1,q+qcnt+1);
int rt;
for(register int l=1, r; l<=qcnt; l=r+1){
Update(rt,1,n,q[l].id);
r=l; while(r<qcnt and q[r+1].x==q[r].x) r++, Update(rt,1,n,q[r].id);
if(!st.count(pii(val1(rt),val2(rt)))) rts[++cnt] = rt, st.insert(pii(val1(rt),val2(rt)));
}
// sort(rts+1,rts+cnt,cmp);
// for(register int i=1; i<cnt; i++) print(rts[i],1,n), puts("");
// return 0;
nth_element(rts+1,rts+k,rts+cnt,cmp);
print(rts[k],1,n);
cout<<len<<'\n';
for(register int i=1; i<=len; i++) printf("%d ",ans[i]);puts("");
return 0;
}
标签:21.5,head,return,int,31,t2,tail,rc,val2 来源: https://www.cnblogs.com/oisdoaiu/p/14929469.html