lemonoil


OI__nothing is impossible


数据结构专题

最后一题无语(有序链剖……)

Problem 1. rotinv

这里写图片描述 这里写图片描述

题解

这里写图片描述

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
#include <cstdio>
#include <iostream>
using namespace std;
const int N = 1000000 + 10;
template<class T>inline void readin(T &resez){
static char ch;
while((ch=getchar())<'0'||ch>'9');resez=ch-48;
while((ch=getchar())>='0'&&ch<='9')resez=resez*10+ch-48;
}
int n;
int a[N+N];
int bit[N*24];
long long ans,cnt;
void build(int pos,int delta) {
for(register int i = pos;i<=n;i+=i&-i)bit[i] += delta;
}
int query(int right){
int rt=0;
for(register int i=right;i;i-=i&-i)rt += bit[i];
return rt;
}
int main() {
freopen("rotinv.in","r",stdin);
freopen("rotinv.out","w",stdout);
readin(n);
for(register int i=1;i<=n;i++) {
readin(a[i]);
a[n+i]=a[i];
}
for(register int i = 1; i <= n; i++ ) {
cnt+=(i-1)-query(a[i]);
build(a[i],+1);
}
for(register int i = n + 1; i <= n + n; i++ ) {
build(a[i-n],-1);
cnt+=n-1-query(a[i]);
cnt-=query(a[i-n]-1);
build(a[i],+1);
ans+=cnt;
}
cout<<ans<<endl;
return 0;
}

Problem 2. rise

这里写图片描述 这里写图片描述

题解

这里写图片描述

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
#include <cstdio>
#include <iostream>
using namespace std;
const int N=500000+10;
template<class T>inline void readin(T &resez){
static char ch;
while((ch=getchar())<'0'||ch>'9');resez=ch-48;
while((ch=getchar())>='0'&&ch<='9')resez=resez*10+ch-48;
}
struct Node{
int left,right,child_left,child_right,maxn;
Node *ch[2];
int find(int h){
if(left==right)return h<maxn;
else return (h<ch[0]->maxn)?ch[0]->find(h)+child_right:ch[1]->find(h);
}
void update(){
maxn=max(ch[0]->maxn,ch[1]->maxn);
child_right=ch[1]->find(ch[0]->maxn);
child_left=ch[0]->child_left+child_right;
}
}pool[N<<1],*point=pool,*root,*a[N];
int n,m,high[N],head,tail,l,r;
Node *build(int left,int right){
Node *node=++point;
node->left=left;
node->right=right;
if(left==right){
node->child_left=1;
node->child_right=0;
node->maxn=high[left];
}else{
int mid=(left+right)>>1;
node->ch[0]=build(left,mid);
node->ch[1]=build(mid+1,right);
node->update();
}
return node;
}
void ask(Node *node,int L,int R){
if(L<=node->left&&node->right<=R){
a[++tail]=node;return;
}
int mid=(node->left+node->right)>>1;
if(L<=mid)ask(node->ch[0],L,R);
if(R>mid)ask(node->ch[1],L,R);
}
int query(int L,int R){
head=1,tail=0;
ask(root,L,R);
int cnt=0,ans=0;
for(register int i=head;i<=tail;i++){
ans+=a[i]->find(cnt);
cnt=max(cnt,a[i]->maxn);
}
return ans;
}
int main(){
freopen("rise.in","r",stdin);
freopen("rise.out","w",stdout);
readin(n),readin(m);
for(register int i=1;i<=n;i++)readin(high[i]);
root=build(1,n);
while(m--){
readin(l),readin(r);
printf("%d\n",query(l,r));
}
return 0;
}

Problem 3. seqmod

(神题特此附上两张图!!!) 这里写图片描述 这里写图片描述 这里写图片描述

题解

这里写图片描述

idy002大神发明了有序链剖。。。然而并不知道。。。 有序链剖(神!!!)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
#include <cstdio>
#include <iostream>
#include <algorithm>
using namespace std;
const int N=100000 + 10;
const int M=N<<1;
const int Mod=31;
template<class T>inline void readin(T &res){
static char ch;
while((ch=getchar())<'0'||ch>'9');res=ch-48;
while((ch=getchar())<='9'&&ch>='0')res=res*10+ch-48;
}
struct Point{
int v,len;
Point(){}
Point(int v,int len):v(v),len(len){}
};
int head[N],wght[M],dest[M],last[M],etot;
int depf[N],siz[N],son[N],top[N],father[N],val[N],in[N],rank[N],deps[N],pos_id;
struct Node{
Point ab,ba;
Node *ls,*rs;
}point_pool[N*4],*tail=point_pool,*root;
void init(){
deps[0]=1;
for(register int i=1;i<N;i++)
deps[i]=deps[i-1]*10%Mod;
}
Point link(const Point &a,const Point &b){
return Point((a.v * deps[b.len] + b.v) % Mod,a.len + b.len);
}
Node *build(int lf,int rg){
Node *nd=++tail;
if(lf == rg){
nd->ab=nd->ba=Point(val[rank[lf]],1);
} else{
int mid=(lf + rg)>>1;
nd->ls=build(lf,mid);
nd->rs=build(mid + 1,rg);
nd->ab=link(nd->ls->ab,nd->rs->ab);
nd->ba=link(nd->rs->ba,nd->ls->ba);
}
return nd;
}
Point query_ab(Node *nd,int lf,int rg,int L,int R){
if(L <= lf && rg <= R) return nd->ab;
int mid=(lf + rg)>>1;
if(R <= mid) return query_ab(nd->ls,lf,mid,L,R);
else if(L>mid) return query_ab(nd->rs,mid+1,rg,L,R);
else return link(
query_ab(nd->ls,lf,mid,L,R),
query_ab(nd->rs,mid+1,rg,L,R));
}
Point query_father(Node *nd,int lf,int rg,int L,int R){
if(L <= lf && rg <= R) return nd->ba;
int mid=(lf + rg)>>1;
if(R <= mid) return query_father(nd->ls,lf,mid,L,R);
else if(L>mid) return query_father(nd->rs,mid+1,rg,L,R);
else return link(
query_father(nd->rs,mid+1,rg,L,R),
query_father(nd->ls,lf,mid,L,R));
}
void adde(int u,int v,int d){
etot++;
dest[etot]=v;
last[etot]=head[u];
wght[etot]=d;
head[u]=etot;
}
void dfs1(int u){
siz[u]=1;
for(register int t=head[u]; t; t=last[t]){
int v=dest[t];
if(v == father[u]) continue;
father[v]=u;
depf[v]=depf[u] + 1;
val[v]=wght[t];
dfs1(v);
siz[u] += siz[v];
if(siz[v]>siz[son[u]]) son[u]=v;
}
}
void dfs2(int u){
in[u]=++pos_id;
rank[pos_id]=u;
if(son[u]){
top[son[u]]=top[u];
dfs2(son[u]);
}
for(register int t=head[u]; t; t=last[t]){
int v=dest[t];
if(v == father[u] || v == son[u]) continue;
top[v]=v;
dfs2(v);
}
}
int query(int u,int v){
Point y_x(0,0),x_y(0,0);
while(top[u]!=top[v]){
if(depf[top[u]]>depf[top[v]]){
y_x=link(y_x,query_father(root,1,pos_id,in[top[u]],in[u]));
u=father[top[u]];
} else{
x_y=link(query_ab(root,1,pos_id,in[top[v]],in[v]),x_y);
v=father[top[v]];
}
}
if(depf[u]>depf[v]){
y_x=link(y_x,query_father(root,1,pos_id,in[v]+1,in[u]));
} else if(depf[v]>depf[u]){
x_y=link(query_ab(root,1,pos_id,in[u]+1,in[v]),x_y);
}
Point ans=link(y_x,x_y);
return ans.v;
}
int n,m;
int main(){
freopen("seqmod.in","r",stdin);
freopen("seqmod.out","w",stdout);
readin(n),readin(m);
for(register int i=1;i<n;i++){
int u,v,d;
readin(u),readin(v),readin(d),
adde(u,v,d);
adde(v,u,d);
}
init();
father[1]=1;
depf[1]=0;
dfs1(1);
top[1]=1;
dfs2(1);
root=build(1,pos_id);
while(m--){
int u,v;
readin(u),readin(v);
printf("%d\n",query(u,v));
}
return 0;
}

click it and link me

Launch CodeCogs Equation Editor