最后一题无语(有序链剖……)
Problem 1. rotinv
题解
#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
题解
#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大神发明了有序链剖。。。然而并不知道。。。
有序链剖(神!!!)
#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;
}