http://www.lydsy.com/JudgeOnline/problem.php?id=2141
明明是个水水哒树套树,可我就是狂T
难道B站会专门卡我的树套树不成。。。。?
找了两份AC代码,一个分块,一个树套树
怎么拍我都比那树套树快!!!
可只有我的会T。。。。。。。。。。。。。。。。。。。。。。。。。。
为什么B站看我树套树那么不顺眼捏。?
m扩大10倍:
my code:(TLE)
//#define _TEST _TEST
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <iostream>
#include <cmath>
#include <algorithm>
#include <map>
using namespace std;
/************************************************
Code By willinglive Blog:http://willinglive.cf
************************************************/
#define rep(i,l,r) for(int i=l,___t=(r);i<=___t;i++)
#define per(i,r,l) for(int i=r,___t=(l);i>=___t;i--)
#define MS(arr,x) memset(arr,x,sizeof(arr))
#define LL long long
#define INE(i,u,e) for(int i=head[u];~i;i=e[i].next)
inline const int getint()
{
int r=0,k=1;char c=getchar();
for(;c<'0'||c>'9';c=getchar())if(c=='-')k=-1;
for(;c>='0'&&c<='9';c=getchar())r=r*10+c-'0';
return k*r;
}
/
int n,m;
int h[20010],cnt;
map<int,int>M;
/
int rnd(){return rand()<<16|rand();}
namespace Treap
{//
#define LS T[o].l
#define RS T[o].r
int root,sz;
struct data{int l,r,s,rnd,w;}T[10000010];
void update(int o){T[o].s=T[LS].s+T[RS].s+1;}
void l_rot(int &o){int t=RS;RS=T[t].l;T[t].l=o;T[t].s=T[o].s;update(o);o=t;}
void r_rot(int &o){int t=LS;LS=T[t].r;T[t].r=o;T[t].s=T[o].s;update(o);o=t;}
void insert(int &o,int x)
{
if(!o)
{
o=++sz; T[o].s=1; T[o].rnd=rnd(); T[o].w=x;
return;
}
T[o].s++;
if(x<T[o].w)
{
insert(LS,x);
if(T[LS].rnd<T[o].rnd) r_rot(o);
}
else
{
insert(RS,x);
if(T[RS].rnd<T[o].rnd) l_rot(o);
}
}
void del(int &o,int x)
{
if(!o) return;
if(x==T[o].w)
{
if(LS==0||RS==0) o=LS+RS;
else if(T[LS].rnd<T[RS].rnd) r_rot(o),del(o,x);
else l_rot(o),del(o,x);
return;
}
T[o].s--;
if(x<T[o].w) del(LS,x);
else del(RS,x);
}
int getgreater(int o,int x)
{
if(!o) return 0;
if(T[o].w==x) return T[RS].s+1;
if(x<T[o].w) return T[RS].s+1+getgreater(LS,x);
else return getgreater(RS,x);
}
int getlower(int o,int x)
{
if(!o) return 0;
if(T[o].w==x) return T[LS].s+1;
if(x<T[o].w) return getlower(LS,x);
else return T[LS].s+1+getlower(RS,x);
}
}//
namespace BIT
{//
int root[20010];
void insert(int o,int x)
{
using namespace Treap;
for(;o<=n;o+=o&-o)
Treap::insert(root[o],x);
}
void del(int o,int x)
{
using namespace Treap;
for(;o<=n;o+=o&-o)
Treap::del(root[o],x);
}
int getgreater(int o,int x)
{
using namespace Treap;
int s=0;
for(;o;o-=o&-o)
s+=Treap::getgreater(root[o],x);
return s;
}
int getlower(int o,int x)
{
using namespace Treap;
int s=0;
for(;o>0;o-=o&-o)
s+=Treap::getlower(root[o],x);
return s;
}
}//
/
void input()
{
srand(1313131);
n=getint();
rep(i,1,n) h[i]=getint(),M[h[i]]=i;
for(map<int,int>::iterator it=M.begin();it!=M.end();it++)
h[it->second]=++cnt;
m=getint();
}
void solve()
{
using namespace BIT;
int ans=0;
int l,r;
rep(i,1,n)
{
insert(i,h[i]);
ans+=getgreater(i-1,h[i]);
}
printf("%d\n",ans);
while(m--)
{
l=getint(); r=getint();
//两句特判!!!!!!!!!!!!!!!!!!!!!
if(l>r) swap(l,r);
if(l==r){printf("%d\n",ans);continue;}
ans+=2*(getgreater(r-1,h[l]) - getgreater(l,h[l]))+l-r+1;
ans+=2*(getlower(r-1,h[r]) - getlower(l,h[r]))+l-r+1;
if(h[l]>h[r]) ans--;
else ans++;
del(l,h[l]); insert(r,h[l]);
del(r,h[r]); insert(l,h[r]);
swap(h[l],h[r]);
printf("%d\n",ans);
}
}
/
int main()
{
#ifndef _TEST
freopen("std.in","r",stdin); freopen("std.out","w",stdout);
#endif
input(),
solve();
return 0;
}
hzwer:比我的快一点
注意一点:
分块的大小应该为sqrt(n*logn)这样时间复杂度会减小O(sqrt(logn))
#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#define ll long long
#define inf 1000000000
using namespace std;
inline int read()
{
int x=0,f=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
return x*f;
}
int n,m,block,cnt,ans;
int l[605],r[605];
int a[20005],b[20005],t[20005],disc[20005],belong[20005];
inline int lowbit(int x){return x&(-x);}
inline void update(int x,int val)
{
for(int i=x;i<=n;i+=lowbit(i))
t[i]+=val;
}
inline int query(int x)
{
int sum=0;
for(int i=x;i;i-=lowbit(i))
sum+=t[i];
return sum;
}
inline int disc_find(int x)
{
int l=1,r=n;
while(l<=r)
{
int mid=(l+r)>>1;
if(disc[mid]==x)return mid;
else if(disc[mid]<x)l=mid+1;
else r=mid-1;
}
}
int finddown(int l,int r,int x)
{
int ans=l-1,t=l;
while(l<=r)
{
int mid=(l+r)>>1;
if(a[mid]<x)ans=mid,l=mid+1;
else r=mid-1;
}
return ans-t+1;
}
int findup(int l,int r,int x)
{
int ans=r+1,t=r;
while(l<=r)
{
int mid=(l+r)>>1;
if(a[mid]>x)ans=mid,r=mid-1;
else l=mid+1;
}
return t-ans+1;
}
void rebuild(int x)
{
for(int i=l[x];i<=r[x];i++)
a[i]=b[i];
sort(a+l[x],a+r[x]+1);
}
void pre()
{
for(int i=n;i;i--)
{
ans+=query(b[i]-1);
update(b[i],1);
}
for(int i=1;i<=cnt;i++)
rebuild(i);
}
void solve(int x,int y)
{
if(x==y)return;
int L=r[belong[x]],R=l[belong[y]];
if(b[x]<b[y])ans++;
if(b[x]>b[y])ans--;
if(belong[x]==belong[y])
{
for(int i=x+1;i<y;i++)
{
if(b[i]>b[x])ans++;
if(b[i]<b[x])ans--;
if(b[i]>b[y])ans--;
if(b[i]<b[y])ans++;
}
}
else
{
for(int i=x+1;i<=L;i++)
{
if(b[i]>b[x])ans++;
if(b[i]<b[x])ans--;
if(b[i]>b[y])ans--;
if(b[i]<b[y])ans++;
}
for(int i=R;i<y;i++)
{
if(b[i]>b[x])ans++;
if(b[i]<b[x])ans--;
if(b[i]>b[y])ans--;
if(b[i]<b[y])ans++;
}
for(int i=belong[x]+1;i<belong[y];i++)
{
ans-=finddown(l[i],r[i],b[x]);
ans+=finddown(l[i],r[i],b[y]);
ans+=findup(l[i],r[i],b[x]);
ans-=findup(l[i],r[i],b[y]);
}
}
swap(b[x],b[y]);
rebuild(belong[x]);rebuild(belong[y]);
}
int main()
{
freopen("std.in","r",stdin); freopen("hzwer.out","w",stdout);
n=read();
block=sqrt(n);
if(n%block)cnt=n/block+1;
else cnt=n/block;
for(int i=1;i<=cnt;i++)
l[i]=(i-1)*block+1,r[i]=i*block;
r[cnt]=n;
for(int i=1;i<=n;i++)
belong[i]=(i-1)/block+1;
for(int i=1;i<=n;i++)
disc[i]=a[i]=read();
sort(disc+1,disc+n+1);
for(int i=1;i<=n;i++)
a[i]=b[i]=disc_find(a[i]);
pre();
printf("%d\n",ans);
m=read();
for(int i=1;i<=m;i++)
{
int x=read(),y=read();
if(x>y)swap(x,y);
solve(x,y);
printf("%d\n",ans);
}
return 0;
}
明显慢啊啊啊
#include <iostream>
#include <cstdio>
#include <string.h>
#include <algorithm>
#include <cmath>
#include <vector>
#include <queue>
#include <set>
#include <stack>
#include <string>
#include <map>
#define max(x,y) ((x)>(y)?(x):(y))
#define min(x,y) ((x)<(y)?(x):(y))
#define abs(x) ((x)>=0?(x):-(x))
#define i64 long long
#define u32 unsigned int
#define u64 unsigned long long
#define clr(x,y) memset(x,y,sizeof(x))
#define CLR(x) x.clear()
#define ph(x) push(x)
#define pb(x) push_back(x)
#define Len(x) x.length()
#define SZ(x) x.size()
#define PI acos(-1.0)
#define sqr(x) ((x)*(x))
#define MP(x,y) make_pair(x,y)
#define EPS 1e-10
#define FOR0(i,x) for(i=0;i<x;i++)
#define FOR1(i,x) for(i=1;i<=x;i++)
#define FOR(i,a,b) for(i=a;i<=b;i++)
#define FORL0(i,a) for(i=a;i>=0;i--)
#define FORL1(i,a) for(i=a;i>=1;i--)
#define FORL(i,a,b)for(i=a;i>=b;i--)
#define rush() int CC;for(scanf("%d",&CC);CC--;)
#define Rush(n) while(scanf("%d",&n)!=-1)
using namespace std;
void RD(int &x){scanf("%d",&x);}
void RD(i64 &x){scanf("%lld",&x);}
void RD(u64 &x){scanf("%llu",&x);}
void RD(u32 &x){scanf("%u",&x);}
void RD(double &x){scanf("%lf",&x);}
void RD(int &x,int &y){scanf("%d%d",&x,&y);}
void RD(i64 &x,i64 &y){scanf("%lld%lld",&x,&y);}
void RD(u32 &x,u32 &y){scanf("%u%u",&x,&y);}
void RD(double &x,double &y){scanf("%lf%lf",&x,&y);}
void RD(int &x,int &y,int &z){scanf("%d%d%d",&x,&y,&z);}
void RD(i64 &x,i64 &y,i64 &z){scanf("%lld%lld%lld",&x,&y,&z);}
void RD(u32 &x,u32 &y,u32 &z){scanf("%u%u%u",&x,&y,&z);}
void RD(double &x,double &y,double &z){scanf("%lf%lf%lf",&x,&y,&z);}
void RD(char &x){x=getchar();}
void RD(char *s){scanf("%s",s);}
void RD(string &s){cin>>s;}
void PR(int x) {printf("%d\n",x);}
void PR(int x,int y) {printf("%d %d\n",x,y);}
void PR(i64 x) {printf("%lld\n",x);}
void PR(u32 x) {printf("%u\n",x);}
void PR(u64 x) {printf("%llu\n",x);}
void PR(double x) {printf("%.2lf\n",x);}
void PR(char x) {printf("%c\n",x);}
void PR(char *x) {printf("%s\n",x);}
void PR(string x) {cout<<x<<endl;}
void upMin(int &x,int y) {if(x>y) x=y;}
void upMin(i64 &x,i64 y) {if(x>y) x=y;}
void upMin(double &x,double y) {if(x>y) x=y;}
void upMax(int &x,int y) {if(x<y) x=y;}
void upMax(i64 &x,i64 y) {if(x<y) x=y;}
void upMax(double &x,double y) {if(x<y) x=y;}
const int mod=20101009;
const i64 inf=((i64)1)<<60;
const double dinf=1000000000000000000.0;
const int INF=2147483647;
const int N=20005;
struct node
{
int val,size,pri,L,R,cnt;
};
node a[N*300];
int e;
int newNode(int val)
{
int x=++e;;
a[x].val=val;
a[x].size=1;
a[x].cnt=1;
a[x].L=a[x].R=0;
a[x].pri=rand();
return x;
}
void pushUp(int x)
{
if(x==0) return;
a[x].size=a[x].cnt+a[a[x].L].size+a[a[x].R].size;
}
void rotL(int &x)
{
int y=a[x].R;
a[x].R=a[y].L;
a[y].L=x;
pushUp(x);
pushUp(y);
x=y;
}
void rotR(int &x)
{
int y=a[x].L;
a[x].L=a[y].R;
a[y].R=x;
pushUp(x);
pushUp(y);
x=y;
}
void insert(int &k,int val)
{
if(k==0) k=newNode(val);
else if(val<a[k].val)
{
insert(a[k].L,val);
if(a[a[k].L].pri>a[k].pri) rotR(k);
}
else if(val>a[k].val)
{
insert(a[k].R,val);
if(a[a[k].R].pri>a[k].pri) rotL(k);
}
else a[k].cnt++;
pushUp(k);
}
void del(int val,int &k)
{
if(k==0) return;
else if(val<a[k].val) del(val,a[k].L);
else if(val>a[k].val) del(val,a[k].R);
else
{
a[k].cnt--;
if(a[k].cnt<=0)
{
if(a[k].L==0&&a[k].R==0) k=0;
else if(a[k].L==0) k=a[k].R;
else if(a[k].R==0) k=a[k].L;
else
{
if(a[a[k].L].pri<a[a[k].R].pri) rotL(k),del(val,a[k].L);
else rotR(k),del(val,a[k].R);
}
}
}
pushUp(k);
}
int d[N];
int getCnt(int t,int x)
{
if(t==0) return 0;
if(a[t].val==x)
{
return a[a[t].L].size+a[t].cnt;
}
if(a[t].val>x) return getCnt(a[t].L,x);
return a[t].cnt+a[a[t].L].size+getCnt(a[t].R,x);
}
int n,m;
int A[N];
void Set(int x,int k)
{
while(x<=n)
{
insert(A[x],k);
x+=x&-x;
}
}
void erase(int x,int k)
{
while(x<=n)
{
del(k,A[x]);
x+=x&-x;
}
}
int get(int x,int k)
{
int ans=0;
while(x)
{
ans+=getCnt(A[x],k);
x-=x&-x;
}
return ans;
}
pair<int,int> cal(int L,int R,int x)
{
i64 a=get(R,x)-get(L-1,x);
i64 b=get(R,x-1)-get(L-1,x-1);
return MP(a-b,b);
}
int p[N];
int find(int low,int high,int x)
{
int M;
while(low<=high)
{
M=(low+high)>>1;
if(p[M]==x) return M;
if(p[M]>x) high=M-1;
else low=M+1;
}
}
void getInt(int &x)
{
char c=getchar();
while(!isdigit(c)) c=getchar();
x=0;
while(isdigit(c)) x=x*10+c-'0',c=getchar();
}
int main()
{
freopen("std.in","r",stdin); freopen("ac.out","w",stdout);
getInt(n);
int i;
FOR1(i,n) getInt(d[i]),p[i]=d[i];
sort(p+1,p+n+1);
int M=unique(p+1,p+n+1)-(p+1);
FOR1(i,n) d[i]=find(1,M,d[i]);
i64 sum=0;
pair<int,int> temp;
FOR1(i,n)
{
Set(i,d[i]);
temp=cal(1,i-1,d[i]);
sum+=i-1-temp.first-temp.second;
}
PR(sum);
RD(m);
int x,y;
while(m--)
{
getInt(x);
getInt(y);
if(x>y) swap(x,y);
if(d[x]==d[y])
{
PR(sum);
continue;
}
if(d[x]>d[y]) sum--;
else sum++;
if(y-x>1)
{
temp=cal(x+1,y-1,d[x]);
sum-=temp.second;
sum+=y-x-1-temp.first-temp.second;
temp=cal(x+1,y-1,d[y]);
sum+=temp.second;
sum-=y-x-1-temp.first-temp.second;
}
erase(x,d[x]);
erase(y,d[y]);
swap(d[x],d[y]);
Set(x,d[x]);
Set(y,d[y]);
PR(sum);
}
}
附赠makedata.cpp,求查错。。。。。。。。。。。。。。。
//#define _TEST _TEST
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <iostream>
#include <cmath>
#include <algorithm>
#include <time.h>
#include <map>
using namespace std;
/************************************************
Code By willinglive Blog:http://willinglive.cf
************************************************/
#define rep(i,l,r) for(int i=l,___t=(r);i<=___t;i++)
#define per(i,r,l) for(int i=r,___t=(l);i>=___t;i--)
#define MS(arr,x) memset(arr,x,sizeof(arr))
#define LL long long
#define INE(i,u,e) for(int i=head[u];~i;i=e[i].next)
inline const int getint()
{
int r=0,k=1;char c=getchar();
for(;c<'0'||c>'9';c=getchar())if(c=='-')k=-1;
for(;c>='0'&&c<='9';c=getchar())r=r*10+c-'0';
return k*r;
}
/
int n,m;
map<int,int>M;
/
int rnd(){return rand()<<16|rand();}
/
void input()
{
srand(time(0));
}
void solve()
{
n=20000; m=2000;
printf("%d\n",n);
rep(i,1,n)
{
int x=rnd()%1000000000+1;
while(M[x]) x=rnd()%1000000000+1;
M[x]=1;
printf("%d ",x);
}
printf("\n%d\n",m);
rep(i,1,m)
{
int l=rnd()%n+1;
int r=rnd()%n+1;
printf("%d %d\n",l,r);
}
}
/
int main()
{
#ifndef _TEST
freopen("std.in","r",stdin); freopen("std.in","w",stdout);
#endif
input(),
solve();
return 0;
}